home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSC / kmsrexx.c < prev    next >
C/C++ Source or Header  |  1995-09-16  |  76KB  |  2,726 lines

  1. /**********************************
  2.  *              KMS               *
  3.  **********************************
  4.  *  ©1995 by BlackMagic Software  *
  5.  **********************************
  6.  *                                *
  7.  **********************************/
  8.  
  9. #include <KMS/KMS.h>
  10. #include <KMS/KMS_rexx.h>
  11. #include <KMS/KMS_devlib.h>
  12.  
  13. Prototype VOID KMSRexxDisp(struct RexxMsg *, struct rexxCommandList *, STRPTR);
  14. Prototype VOID RexxErr(UWORD);
  15. Prototype VOID RexxOK(STRPTR, STRPTR);
  16. Prototype VOID Rexx_SHUTDOWN(struct RexxMsg *, LONG []);
  17. Prototype VOID Rexx_LOCKPORT(struct RexxMsg *, LONG []);
  18. Prototype VOID Rexx_UNLOCKPORT(struct RexxMsg *, LONG []);
  19. Prototype VOID Rexx_LOGIN(struct RexxMsg *, LONG []);
  20. Prototype VOID Rexx_LOGOUT(struct RexxMsg *, LONG []);
  21. Prototype VOID Rexx_OUT(struct RexxMsg *, LONG []);
  22. Prototype VOID Rexx_OUTFILE(struct RexxMsg *, LONG []);
  23. Prototype VOID Rexx_REFRESH(struct RexxMsg *, LONG []);
  24. Prototype VOID Rexx_GETMSG(struct RexxMsg *, LONG []);
  25. Prototype VOID Rexx_GETAREA(struct RexxMsg *, LONG []);
  26. Prototype VOID Rexx_GETACCESS(struct RexxMsg *, LONG []);
  27. Prototype VOID Rexx_INPUTSTR(struct RexxMsg *, LONG []);
  28. Prototype VOID Rexx_GETUSER(struct RexxMsg *, LONG []);
  29. Prototype VOID Rexx_SETUSER(struct RexxMsg *, LONG []);
  30. Prototype VOID Rexx_ADDUSER(struct RexxMsg *, LONG []);
  31. Prototype VOID Rexx_KMSEXEC(struct RexxMsg *, LONG []);
  32. Prototype VOID Rexx_LOGENTRY(struct RexxMsg *, LONG []);
  33. Prototype VOID Rexx_SETCONMODE(struct RexxMsg *, LONG []);
  34. Prototype VOID Rexx_GETCONFIG(struct RexxMsg *, LONG []);
  35. Prototype VOID Rexx_GETSESSION(struct RexxMsg *, LONG []);
  36. Prototype VOID Rexx_GETFTP(struct RexxMsg *, LONG []);
  37. Prototype VOID Rexx_GETAREALIST(struct RexxMsg *, LONG []);
  38. Prototype VOID Rexx_SPYWIN(struct RexxMsg *, LONG []);
  39. Prototype VOID ReadUserStem(struct Userdaten *, struct RexxMsg *, STRPTR);
  40. Prototype BOOL SendPortMsg(STRPTR, WORD, UWORD);
  41. Prototype BOOL ExecKMSRexx(STRPTR);
  42. Prototype VOID RexxCmdParse(STRPTR, UBYTE *, STRPTR *);
  43. Prototype BOOL CheckStack(VOID);
  44.  
  45. extern LONG SetMode(BPTR, LONG);
  46. extern LONG IsInteractive(BPTR);
  47. extern VOID KPrintF(APTR, ...);
  48.  
  49. /***********************************
  50.  * Globale Variable                *
  51.  ***********************************/
  52.  
  53. /* Liste implementierter Kommandos (lower case!) */
  54.  
  55. struct rexxCommandList RCL[] =
  56.    {
  57.    {"shutdown",    (APTR)&Rexx_SHUTDOWN,    "DELAY/K/N"},
  58.    {"lockport",    (APTR)&Rexx_LOCKPORT,    "DELAY/K/N"},
  59.    {"unlockport",  (APTR)&Rexx_UNLOCKPORT,  ""},
  60.    {"login",       (APTR)&Rexx_LOGIN,       "USER/A,PASSWORD"},
  61.    {"logout",      (APTR)&Rexx_LOGOUT,      ""},
  62.    {"out",         (APTR)&Rexx_OUT,         "QUERY/S,ENABLE/S,DISABLE/S,QUIET/S,NOLINE/S,CHAT/S,NOPARSE/S,TEXT/F"},
  63.    {"outfile",     (APTR)&Rexx_OUTFILE,     "FILE/A,AUTOEXT/S"},
  64.    {"refresh",     (APTR)&Rexx_REFRESH,     "UMS/S,ALL/S"},
  65.    {"getmsg",      (APTR)&Rexx_GETMSG,      "NUMBER/N,MSGNUM/S,MSGTEXT/S,FROMNAME/S,FROMADDR/S,TONAME/S,TOADDR/S,MSGID/S,CREATIONDATE/S,REFERID/S,GROUP/S,SUBJECT/S,ATTRIBUTES/S,COMMENTS/S,ORGANIZATION/S,DISTRIBUTION/S,ALL/S,VAR/K"},
  66.    {"getarea",     (APTR)&Rexx_GETAREA,     "PATH,ID/S,AREANAME/S,INFO/S,MBNAME/S,TYPE/S,READLEVEL/S,WRITELEVEL/S,EDITLEVEL/S,HOLDNUM/S,HOLDDAYS/S,QOTESTR/S,PQUOTESTR/S,RESENDSTR/S,FORWARDSTR/S,ORIGINSTR/S,ALL/S,VAR/K"},
  67.    {"getaccess",   (APTR)&Rexx_GETACCESS,   "AREA/K,VAR/K"},
  68.    {"inputstr",    (APTR)&Rexx_INPUTSTR,    "PROMPT/K,LENGTH/K/N,DEFTXT/K,CHOICE/K,NUMERIC/S,NOEMPTY/S,CTRLKEYS/S,NOINSERT/S,UPPERCASE/S,AUTOEXIT/S,HIDDEN/S"},
  69.    {"getuser",     (APTR)&Rexx_GETUSER,     "NAME,USERNAME/S,PASSWORD/S,LEVEL/S,LASTCALL/S,CALLS/S,REALNAME/S,STREET/S,CITY/S,PHONE/S,CHARSET/S,FLAGS/S,PROMPT/S,DISKQUOTA/S,PAGELEN/S,LINELEN/S,ACCESSBITS/S,ALL/S,VAR/K"},
  70.    {"setuser",     (APTR)&Rexx_SETUSER,     "NAME,USERNAME/S,PASSWORD/S,LEVEL/S,LASTCALL/S,CALLS/S,REALNAME/S,STREET/S,CITY/S,PHONE/S,CHARSET/S,FLAGS/S,PROMPT/S,DISKQUOTA/S,PAGELEN/S,LINELEN/S,ACCESSBITS/S,ALL/S,VALUE/K/A"},
  71.    {"adduser",     (APTR)&Rexx_ADDUSER,     "VAR/K/A"},
  72.    {"kmsexec",     (APTR)&Rexx_KMSEXEC,     "COMMAND/F/A"},
  73.    {"logentry",    (APTR)&Rexx_LOGENTRY,    "TEXT/F"},
  74.    {"setcon",      (APTR)&Rexx_SETCONMODE,  "RAW/S,COOKED/S"},
  75.    {"getconfig",   (APTR)&Rexx_GETCONFIG,   "DATDIR/S,TEXTDIR/S,REXXDIR/S,USERDIR/S,LOGDIR/S,BINDIR/S,DOORDIR/S,TEMPDIR/S,ACCBITS/S,ALL/S,VAR/K"},
  76.    {"getsession",  (APTR)&Rexx_GETSESSION,  "PID/S,USERNAME/S,LOGINTIME/S,PRIVDIR/S,DEVICE/S,SERDEV/S,SERUNIT/S,BPS/S,ALL/S,VAR/K"},
  77.    {"getftp",      (APTR)&Rexx_GETFTP,      "VAR/K/A"},
  78.    {"getarealist", (APTR)&Rexx_GETAREALIST, "PATH,VAR/K/A"},
  79.    {"spywin",      (APTR)&Rexx_SPYWIN,      "OPEN/K,CLOSE/S,SUSPEND/S,CONTINUE/S"},
  80.    {NULL, NULL, NULL}
  81.    };
  82.  
  83. /* Liste für temporären Rexx-Port */
  84.  
  85. struct rexxCommandList TempRCL[] =
  86.    {
  87.    {NULL, NULL, NULL}
  88.    };
  89.  
  90. #define ERR_INVALID_PARAMS              1
  91. #define ERR_TOO_MANY_PARAMS             2
  92. #define ERR_ALREADY_LOCKED              3
  93. #define ERR_NOT_LOCKED                  4
  94. #define ERR_TOO_FEW_PARAMS              5
  95. #define ERR_NO_LOGIN                    6
  96. #define ERR_USER_ACTIVE                 7
  97. #define ERR_INVALID_PASSWORD            8
  98. #define ERR_NO_SUCH_USER                9
  99. #define ERR_NO_SUCH_UMS_USER            10
  100. #define ERR_NO_MSG_READ                 11
  101. #define ERR_UMS_READ_ERROR              12
  102. #define ERR_SHUTDOWN                    13
  103. #define ERR_NO_VARNAME                  14
  104. #define ERR_VARNAME_TOO_LONG            15
  105. #define ERR_TIMEOUT                     16
  106. #define ERR_OUT_OF_MEMORY               17
  107. #define ERR_ONLY_CURRENT_PWD            18
  108. #define ERR_FILE_NOT_FOUND              19
  109. #define ERR_NO_SUCH_AREA                20
  110. #define ERR_USER_EXISTS                 21
  111. #define ERR_USER_NOT_CREATED            22
  112.  
  113. STRPTR RexxErrStr[23] =
  114.    {
  115.    "",
  116.    " 1: Invalid parameters",
  117.    " 2: Too many parameters",
  118.    " 3: Port already locked",
  119.    " 4: Port is not locked",
  120.    " 5: Too few parameters",
  121.    " 6: No user logged in",
  122.    " 7: A user is already logged in",
  123.    " 8: Invalid password",
  124.    " 9: No such user registered",
  125.    "10: No such user in UMS.CONFIG",
  126.    "11: No msg active",
  127.    "12: UMS read error",
  128.    "13: System shutting down",
  129.    "14: No stemname set",
  130.    "15: Name too long",
  131.    "16: Onlinetime exceeded",
  132.    "17: Out of memory",
  133.    "18: Only password of current user available",
  134.    "19: File not found",
  135.    "20: No such area",
  136.    "21: User already exists",
  137.    "22: Error while creating user"
  138.    };
  139.  
  140. UBYTE KMSRexx = 0;
  141.  
  142. static STRPTR KMSRexxStr;
  143. static STRPTR KMSRexxVar;
  144. static ULONG KMSRexxRes;
  145. static UBYTE KMSRexxErr;
  146.  
  147. extern ULONG RexxSignal;
  148. extern struct MsgPort *MyRexxPort;
  149.  
  150. extern struct KMSBase *KMSBase;
  151. extern struct LocalConfig *KMS_LC;
  152.  
  153. extern UMSAccount MyUMSAccount;
  154. extern UMSAccount SysUMSAccount;
  155.  
  156. extern UBYTE ShutDown, Plop;
  157. extern STRPTR PPArg, PPArg2;
  158.  
  159. extern STRPTR CmdArgV[MAXCMDARGS];
  160. extern UBYTE CmdArgC;
  161.  
  162. extern struct UserNode DummyUser;
  163.  
  164. extern TEXT PathString[];
  165.  
  166. extern BOOL Spying;
  167.  
  168. /*******************************************
  169.  * Rexx-"Dispatch"-Funktion                *
  170.  * -> Ausfuehrung interner Rexx-Befehle    *
  171.  * Vorsicht!: Bei rekursiven Aufrufen      *
  172.  * ist diese Prozedur sehr Stack-intensiv! *
  173.  *******************************************
  174.  * I: RexxMsg, CommandList, Argumente      *
  175.  * O: ---                                  *
  176.  *******************************************/
  177.  
  178. /// "KMSRexxDisp"
  179.  
  180. static VOID (*funktion)(struct RexxMsg *, STRPTR, UBYTE, STRPTR *);
  181. static VOID (*readargfunc)(struct RexxMsg *, LONG[]);
  182.  
  183. VOID KMSRexxDisp(struct RexxMsg *msg, struct rexxCommandList *dat, STRPTR p)
  184.    {
  185.    KMSRexxStr = NULL;
  186.    KMSRexxVar = NULL;
  187.    KMSRexxRes = 0;
  188.    KMSRexxErr = 0;
  189.  
  190.    if (CheckStack())
  191.       {
  192.       KMSRexx++;
  193.  
  194.       if (dat->template)
  195.          {
  196.          LONG rxargv[REXXCMDARGS];
  197.          struct RDArgs *rda;
  198.          STRPTR parsebuff;
  199.          UWORD n;
  200.  
  201.          for(n = 0; n < REXXCMDARGS; n++)
  202.             rxargv[n] = NULL;
  203.    
  204.          parsebuff = malloc(strlen(p) + 2);
  205.          if (parsebuff)
  206.             {
  207.             strcpy(parsebuff, p);
  208.             strcat(parsebuff, "\n");
  209.  
  210.             rda = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
  211.             if (rda)
  212.                {
  213.                rda->RDA_ExtHelp = NULL;
  214.                rda->RDA_Source.CS_Buffer = parsebuff;
  215.                rda->RDA_Source.CS_Length = strlen(parsebuff) + 1;
  216.  
  217.                if (rda = ReadArgs(dat->template, rxargv, rda))
  218.                   {
  219.                   readargfunc = dat->userdata;
  220.                   readargfunc(msg, rxargv);
  221.       
  222.                   FreeArgs(rda);
  223.                   }
  224.                else
  225.                   {
  226.                   KMSRexxErr = ERR_INVALID_PARAMS;
  227.                   KMSRexxRes = 20;
  228.                   }
  229.  
  230.                FreeDosObject(DOS_RDARGS, rda);
  231.                }
  232.             else
  233.                {
  234.                KMSRexxErr = ERR_OUT_OF_MEMORY;
  235.                KMSRexxRes = 20;
  236.                }
  237.             
  238.             free(parsebuff);
  239.             }
  240.          else
  241.             {
  242.             KMSRexxErr = ERR_OUT_OF_MEMORY;
  243.             KMSRexxRes = 20;
  244.             }
  245.          }
  246.       else
  247.          {
  248.          STRPTR *argv[REXXCMDARGS];
  249.          STRPTR rexxbuff;
  250.          UBYTE argc;
  251.  
  252.          rexxbuff = malloc(LEN_REXXBUFF+1);
  253.          if (!rexxbuff)
  254.             {
  255.             KMSRexxErr = ERR_OUT_OF_MEMORY;
  256.             KMSRexxRes = 20;
  257.             }
  258.          else
  259.             {
  260.             strcpy(rexxbuff, dat->name);
  261.             strncat(rexxbuff, p, LEN_REXXBUFF-strlen(rexxbuff));
  262.             rexxbuff[LEN_REXXBUFF] = '\0';
  263.  
  264.             argc = 0;
  265.             RexxCmdParse(rexxbuff, &argc, argv); /* Kommando tokenisieren */
  266.  
  267.             funktion = dat->userdata;
  268.             funktion(msg, p, argc, argv);
  269.  
  270.             RexxCmdParse(NULL, &argc, argv); /* Token freigeben */
  271.  
  272.             free(rexxbuff);
  273.             }
  274.          }
  275.  
  276.       KMSRexx--;
  277.       }
  278.    else
  279.       {
  280.       KMSRexxErr = ERR_OUT_OF_MEMORY;
  281.       KMSRexxRes = 20;
  282.       }
  283.  
  284.    if (KMSRexxErr)
  285.       SetARexxLastError(msg, RexxErrStr[KMSRexxErr]);
  286.    else if (KMSRexxVar && KMSRexxStr)
  287.       SetRexxVar((struct Message *)msg, KMSRexxVar, KMSRexxStr, (ULONG)strlen(KMSRexxStr));
  288.  
  289.    replyRexxCmd(msg, KMSRexxRes, KMSRexxStr);
  290.  
  291.    if (KMSRexxStr)
  292.       free(KMSRexxStr);
  293.    if (KMSRexxVar)
  294.       free(KMSRexxVar);
  295.    }
  296.  
  297. ///
  298.  
  299. /***************************************
  300.  * Rexx-Fehler-RESULT-String           *
  301.  ***************************************
  302.  * I: Fehlertext                       *
  303.  * O: ---                              *
  304.  ***************************************/
  305.  
  306. /// "RexxErr"
  307.  
  308. VOID RexxErr(UWORD errnum)
  309.    {
  310.    KMSRexxErr = errnum;
  311.  
  312.    KMSRexxRes = 20;
  313.    }
  314.  
  315. ///
  316.  
  317. /***************************************
  318.  * Rexx-OK-Standard-RESULT-String      *
  319.  ***************************************
  320.  * I: Erfolgstext/-daten, Varname      *
  321.  * O: ---                              *
  322.  ***************************************/
  323.  
  324. /// "RexxOK"
  325.  
  326. VOID RexxOK(STRPTR restxt, STRPTR varname)
  327.    {
  328.    if (restxt)
  329.       KMSRexxStr = strdup(restxt);
  330.    if (varname)
  331.       {
  332.       KMSRexxVar = strdup(varname);
  333.       Upper(KMSRexxVar);
  334.       }
  335.  
  336.    KMSRexxRes = 0;
  337.    }
  338.  
  339. ///
  340.  
  341. /***************************************
  342.  * Rexx-Kommando "SHUTDOWN"            *
  343.  ***************************************
  344.  * I: Parameterstring                  *
  345.  * O: ---                              *
  346.  ***************************************/
  347.  
  348. /// "Rexx_SHUTDOWN"
  349.  
  350. /* "DELAY/K/N" */
  351.  
  352. VOID Rexx_SHUTDOWN(struct RexxMsg *msg, LONG rxargv[])
  353.    {
  354.    TEXT buff[LEN_NUMBER+9+1];
  355.  
  356.    if (rxargv[0]) /* DELAY/K/N */
  357.       {
  358.       SysMsg(SYSEVENT);
  359.  
  360.       ULONG offset = *(ULONG *)rxargv[0];
  361.  
  362.       sprintf(buff, "%d", (UWORD)offset);
  363.       PPArg = buff;
  364.       SysMsg(LOCAL_SHUTDOWN);
  365.       PPArg = NULL;
  366.  
  367.       if (MyUMSAccount)
  368.          {
  369.          WORD timeleft = KMS_LC->Session.MaxConnectTime - (MakeTime(NULL, KMS_LC->Session.LoginTime, 0) / 60);
  370.  
  371.          if (timeleft > (UWORD)offset)
  372.             KMS_LC->Session.MaxConnectTime -= (timeleft - (UWORD)offset);
  373.          }
  374.  
  375.       ShutDown = SHUTDOWN_DELAYED;
  376.       }
  377.    else
  378.       {
  379.       SysMsg(SYSEVENT);
  380.  
  381.       SysMsg(LOCAL_IMM_SHUTDOWN);
  382.  
  383.       if (MyUMSAccount)
  384.          {
  385.          WORD timeleft = KMS_LC->Session.MaxConnectTime - (MakeTime(NULL, KMS_LC->Session.LoginTime, 0) / 60);
  386.  
  387.          if (timeleft > 0)
  388.             KMS_LC->Session.MaxConnectTime -= timeleft;
  389.          }
  390.  
  391.       ShutDown = SHUTDOWN_IMMEDIATE;
  392.       }
  393.    }
  394.  
  395. ///
  396.  
  397. /***************************************
  398.  * Rexx-Kommando "LOCKPORT"            *
  399.  ***************************************
  400.  * I: Parameterstring                  *
  401.  * O: ---                              *
  402.  ***************************************/
  403.  
  404. /// "Rexx_LOCKPORT"
  405.  
  406. /* "DELAY/K/N" */
  407.  
  408. VOID Rexx_LOCKPORT(struct RexxMsg *msg, LONG rxargv[])
  409.    {
  410.    TEXT buff[LEN_NUMBER+9+1];
  411.  
  412.    if (KMS_LC->Locked)
  413.       {
  414.       RexxErr(ERR_ALREADY_LOCKED);
  415.       return;
  416.       }
  417.  
  418.    if (rxargv[0]) /* DELAY/K/N */
  419.       {
  420.       SysMsg(SYSEVENT);
  421.  
  422.       ULONG offset = *(ULONG *)rxargv[0];
  423.  
  424.       sprintf(buff, "%d", (UWORD)offset);
  425.       PPArg = buff;
  426.       SysMsg(LOCAL_LOCK);
  427.       PPArg = NULL;
  428.  
  429.       if (MyUMSAccount)
  430.          {
  431.          WORD timeleft = KMS_LC->Session.MaxConnectTime - (MakeTime(NULL, KMS_LC->Session.LoginTime, 0) / 60);
  432.  
  433.          if (timeleft > (UWORD)offset)
  434.             KMS_LC->Session.MaxConnectTime -= (timeleft - (UWORD)offset);
  435.          }
  436.  
  437.       KMS_LC->Locked = LOCK_DELAYED;
  438.       }
  439.    else
  440.       {
  441.       SysMsg(SYSEVENT);
  442.       SysMsg(LOCAL_IMM_LOCK);
  443.  
  444.       if (MyUMSAccount)
  445.          {
  446.          WORD timeleft = KMS_LC->Session.MaxConnectTime - (MakeTime(NULL, KMS_LC->Session.LoginTime, 0) / 60);
  447.  
  448.          if (timeleft > 0)
  449.             KMS_LC->Session.MaxConnectTime -= timeleft;
  450.          }
  451.  
  452.       KMS_LC->Locked = LOCK_IMMEDIATE;
  453.       Plop = PLOP_LOCKED;
  454.       }
  455.    }
  456.  
  457. ///
  458.  
  459. /***************************************
  460.  * Rexx-Kommando "UNLOCKPORT"          *
  461.  ***************************************
  462.  * I: Parameterstring                  *
  463.  * O: ---                              *
  464.  ***************************************/
  465.  
  466. /// "Rexx_UNLOCKPORT"
  467.  
  468. /* "" */
  469.  
  470. VOID Rexx_UNLOCKPORT(struct RexxMsg *msg, LONG rxargv[])
  471.    {
  472.    if (!KMS_LC->Locked)
  473.       {
  474.       RexxErr(ERR_NOT_LOCKED);
  475.       return;
  476.       }
  477.  
  478.    SysMsg(SYSEVENT);
  479.    SysMsg(LOCAL_UNLOCK);
  480.  
  481.    KMS_LC->Locked = 0;
  482.    }
  483.  
  484. ///
  485.  
  486. /***************************************
  487.  * Rexx-Kommando "LOGIN"               *
  488.  ***************************************
  489.  * I: Parameterstring                  *
  490.  * O: ---                              *
  491.  ***************************************/
  492.  
  493. /// "Rexx_LOGIN"
  494.  
  495. /* "USER/A,PASSWORD" */
  496.  
  497. VOID Rexx_LOGIN(struct RexxMsg *msg, LONG rxargv[])
  498.    {
  499.    struct UserNode *upoint;
  500.    BOOL valid = FALSE;
  501.    STRPTR mct;
  502.    TEXT buff[LEN_NUMBER+18+1];
  503.    TEXT pwd[LEN_PASSWORD+1];
  504.  
  505.    if (MyUMSAccount)
  506.       RexxErr(ERR_USER_ACTIVE);
  507.    else
  508.       {
  509.       if (upoint = UserCheck((STRPTR)rxargv[0]))
  510.          {
  511.          STRPTR pw = UMSReadConfigTags(SysUMSAccount, UMSTAG_CfgUser, upoint->UserData.RealName,
  512.                                                       UMSTAG_CfgName, "PASSWORD",
  513.                                                       TAG_DONE);
  514.          if (!pw || UMSErrNum(SysUMSAccount))
  515.             {
  516.             RexxErr(ERR_NO_SUCH_UMS_USER);
  517.             if (pw)
  518.                UMSFreeConfig(SysUMSAccount, pw);
  519.             return;
  520.             }
  521.  
  522.          if (strlen(pw))
  523.             {
  524.             if (rxargv[1])
  525.                {
  526.                strncpy(pwd, (STRPTR)rxargv[1], LEN_PASSWORD);
  527.                pwd[LEN_PASSWORD] = '\0';
  528.                }
  529.             else
  530.                {
  531.                RexxErr(ERR_INVALID_PASSWORD);
  532.                UMSFreeConfig(SysUMSAccount, pw);
  533.                return;
  534.                }
  535.             }
  536.          else if (rxargv[1])
  537.             {
  538.             if (strlen((STRPTR)rxargv[1]))
  539.                {
  540.                RexxErr(ERR_INVALID_PASSWORD);
  541.                UMSFreeConfig(SysUMSAccount, pw);
  542.                return;
  543.                }
  544.             else
  545.                *pwd = '\0';
  546.             }
  547.          else
  548.             *pwd = '\0';
  549.  
  550.          UMSFreeConfig(SysUMSAccount, pw);
  551.  
  552.          TEXT varbuff[32] = "";
  553.          GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  554.          if (!(MyUMSAccount = UMSRLogin(varbuff, upoint->UserData.RealName, pwd)))
  555.             {
  556.             RexxErr(ERR_NO_SUCH_UMS_USER);
  557.             return;
  558.             }
  559.          else
  560.             valid = TRUE;
  561.          }
  562.       else
  563.          {
  564.          RexxErr(ERR_NO_SUCH_USER);
  565.          return;
  566.          }
  567.  
  568.       if (valid)
  569.          {
  570.          Plop = 0;
  571.  
  572.          KMS_LC->Session.CurrentUser = upoint;
  573.  
  574.          InitUMS();
  575.  
  576.          KMS_LC->Session.HistPoint = KMS_LC->HistoryList.mlh_Head;
  577.          KMS_LC->Session.LoginTime = time(NULL);   /* Startzeit festhalten */
  578.          KMS_LC->Session.MaxConnectTime = KMSBase->MaxConnectTime; /* Maximal-Verbindungszeit */
  579.          KMS_LC->Session.Warnings = 0;             /* Inputtimeout-Warnungen = 0 */
  580.          KMS_LC->Session.Echo = TRUE;              /* Echo ein */
  581.          KMS_LC->Session.CommMode = 0;             /* Port-Msgs erlaubt */
  582.          KMS_LC->Session.Refresh = FALSE;
  583.          strcpy(KMS_LC->Session.Password, pwd);
  584.          *KMS_LC->Session.CurrCmd = '\0';
  585.          KMS_LC->Session.LineSpeed = 0;
  586.  
  587.          /* Area-Initialisierung */
  588.  
  589.          TakeASem(FALSE);
  590.          KMS_LC->Session.CurrentArea = SetArea(1); /* Aktuelle Area = Private Mail */
  591.          DropASem();
  592.          KMS_LC->Session.CurrentAccess = CheckAccess(KMS_LC->Session.CurrentArea);
  593.          SelectArea(KMS_LC->Session.CurrentArea->AreaData.MBName);
  594.  
  595.          /* Maximal-Verbindungszeit nach Level */
  596.  
  597.          sprintf(buff, "KMS.maxconnecttime%d", KMS_LC->Session.CurrentUser->UserData.Level);
  598.          if (mct = UMSReadConfigTags(SysUMSAccount, UMSTAG_CfgName, buff, TAG_DONE))
  599.             {
  600.             if (atoi(mct) >= 0)
  601.                KMS_LC->Session.MaxConnectTime = atoi(mct);
  602.  
  603.             UMSFreeConfig(SysUMSAccount, mct);
  604.             }
  605.  
  606.          MsgPrint(NULL, 0);
  607.          ReadMsg(0, RF_RESET);
  608.  
  609.          PPArg = KMS_LC->Session.CurrentUser->UserData.Name;
  610.          SysMsg(KMS_USER_ENTERED);
  611.          PPArg = NULL;
  612.          }
  613.       }
  614.    }
  615.  
  616. ///
  617.  
  618. /***************************************
  619.  * Rexx-Kommando "LOGOUT"              *
  620.  ***************************************
  621.  * I: Parameterstring                  *
  622.  * O: ---                              *
  623.  ***************************************/
  624.  
  625. /// "Rexx_LOGOUT"
  626.  
  627. /* "" */
  628.  
  629. VOID Rexx_LOGOUT(struct RexxMsg *msg, LONG rxargv[])
  630.    {
  631.    if (!MyUMSAccount)
  632.       RexxErr(ERR_NO_LOGIN);
  633.    else
  634.       {
  635.       /* Logout-Aktionen */
  636.  
  637.       LogoutUser();
  638.  
  639.       Plop = PLOP_LOGOUT;
  640.       }
  641.    }
  642.  
  643. ///
  644.  
  645. /***************************************
  646.  * Rexx-Kommando "OUT"                 *
  647.  ***************************************
  648.  * I: Parameterstring                  *
  649.  * O: ---                              *
  650.  ***************************************/
  651.  
  652. /// Rexx_OUT
  653.  
  654. /* QUERY/S,ENABLE/S,DISABLE/S,QUIET/S,NOLINE/S,CHAT/S,NOPARSE/S,TEXT/F */
  655.  
  656. VOID Rexx_OUT(struct RexxMsg *msg, LONG rxargv[])
  657.    {
  658.    if (rxargv[0]) /* QUERY/S */
  659.       {
  660.       if (KMS_LC->Session.Echo)
  661.          SysMsg(ECHO_ON);
  662.       else
  663.          {
  664.          KMS_LC->Session.Echo = TRUE;
  665.          SysMsg(ECHO_OFF);
  666.          KMS_LC->Session.Echo = FALSE;
  667.          }
  668.       }
  669.    else if (rxargv[1]) /* ENABLE/S */
  670.       {
  671.       KMS_LC->Session.Echo = TRUE;
  672.       if (!rxargv[3]) /* QUIET/S */
  673.          SysMsg(ECHO_ON);
  674.       }
  675.    else if (rxargv[2]) /* DISABLE/S */
  676.       {
  677.       if (!rxargv[3]) /* QUIET/S */
  678.          {
  679.          KMS_LC->Session.Echo = TRUE;
  680.          SysMsg(ECHO_OFF);
  681.          }
  682.       KMS_LC->Session.Echo = FALSE;
  683.       }
  684.    else
  685.       {
  686.       BOOL crsmerk;
  687.  
  688.       if (crsmerk = KMS_LC->Cursor)
  689.          CursorOff();
  690.  
  691.       if (rxargv[4]) /* NOLINE/S */
  692.          {
  693.          if (rxargv[6]) /* NOPARSE/S */
  694.             Print((STRPTR)rxargv[7], PF_NOLF|PF_NOBRK);
  695.          else
  696.             ParsePrint((STRPTR)rxargv[7], PF_NOLF|PF_NOBRK);
  697.          }
  698.       else if (rxargv[5]) /* CHAT/S */
  699.          ChatPrint((STRPTR)rxargv[7]);
  700.       else
  701.          {
  702.          if (rxargv[6]) /* NOPARSE/S */
  703.             Print((STRPTR)rxargv[7], PF_NOBRK);
  704.          else
  705.             ParsePrint((STRPTR)rxargv[7], PF_NOBRK);
  706.          }
  707.  
  708.       if (crsmerk)
  709.          CursorOn();
  710.       }
  711.  
  712.    KMS_LC->Session.Refresh = TRUE;
  713.    }
  714.  
  715. ///
  716.  
  717. /***************************************
  718.  * Rexx-Kommando "OUTFILE"             *
  719.  ***************************************
  720.  * I: Parameterstring                  *
  721.  * O: ---                              *
  722.  ***************************************/
  723.  
  724. /// "Rexx_OUTFILE"
  725.  
  726. /* "FILE/A,AUTOEXT/S" */
  727.  
  728. VOID Rexx_OUTFILE(struct RexxMsg *msg, LONG rxargv[])
  729.    {
  730.    BOOL modemerk;
  731.    UWORD flag = 0;
  732.  
  733.    if (!(modemerk = KMS_LC->RawMode))
  734.       {
  735.       if (IsInteractive(KMS_LC->InHandle))
  736.          SetMode(KMS_LC->InHandle, 1); // RAW: Modus
  737.       KMS_LC->RawMode = TRUE;
  738.       }
  739.  
  740.    if (rxargv[1]) /* AUTOEXT/S */
  741.       flag = SF_CHOOSEEXT;
  742.  
  743.    if (!SendFile((STRPTR)rxargv[0], flag))
  744.       RexxErr(ERR_FILE_NOT_FOUND);
  745.  
  746.    if (!modemerk)
  747.       {
  748.       if (IsInteractive(KMS_LC->InHandle))
  749.          SetMode(KMS_LC->InHandle, 0); // CON: Modus
  750.       KMS_LC->RawMode = FALSE;
  751.       }
  752.  
  753.    KMS_LC->Session.Refresh = TRUE;
  754.    }
  755.  
  756. ///
  757.  
  758. /***************************************
  759.  * Rexx-Kommando "REFRESH"             *
  760.  ***************************************
  761.  * I: Parameterstring                  *
  762.  * O: ---                              *
  763.  ***************************************/
  764.  
  765. /// "Rexx_REFRESH"
  766.  
  767. /* "UMS/S,ALL/S" */
  768.  
  769. VOID Rexx_REFRESH(struct RexxMsg *msg, LONG rxargv[])
  770.    {
  771.    BOOL ums = FALSE;
  772.  
  773.    if (!MyUMSAccount)
  774.       RexxErr(ERR_NO_LOGIN);
  775.    else if (rxargv[0]) /* UMS/S */
  776.       ums = TRUE;
  777.    else if (rxargv[1]) /* ALL/S */
  778.       ums = TRUE;
  779.  
  780.    if (ums)
  781.       {
  782.       // UMS-Daten neu initialisieren
  783.  
  784.       if (CheckNewMail())
  785.          KMS_LC->Session.Refresh = TRUE;
  786.       }
  787.    }
  788.  
  789. ///
  790.  
  791. /***************************************
  792.  * Rexx-Kommando "GETMSG"              *
  793.  ***************************************
  794.  * I: Parameterstring                  *
  795.  * O: ---                              *
  796.  ***************************************/
  797.  
  798. /// "Rexx_GETMSG"
  799.  
  800. /* NUMBER/N,MSGNUM/S,MSGTEXT/S,FROMNAME/S,FROMADDR/S,TONAME/S,TOADDR/S,MSGID/S,
  801.    CREATIONDATE/S,REFERID/S,GROUP/S,SUBJECT/S,ATTRIBUTES/S,COMMENTS/S,
  802.    ORGANIZATION/S,DISTRIBUTION/S,ALL/S,VAR/K */
  803.  
  804. extern UMSMsgNum Lastmsg;
  805.  
  806. static STRPTR rMsgText = NULL;
  807. static STRPTR rFromName = NULL;
  808. static STRPTR rFromAddr = NULL;
  809. static STRPTR rToName = NULL;
  810. static STRPTR rToAddr = NULL;
  811. static STRPTR rMsgID = NULL;
  812. static STRPTR rCreationDate = NULL;
  813. static STRPTR rReceiveDate = NULL;
  814. static STRPTR rReferID = NULL;
  815. static STRPTR rGroup = NULL;
  816. static STRPTR rSubject = NULL;
  817. static STRPTR rAttributes = NULL;
  818. static STRPTR rComments = NULL;
  819. static STRPTR rOrganization = NULL;
  820. static STRPTR rDistribution = NULL;
  821.  
  822. static struct TagItem readTags[16] =
  823.    {
  824.    {UMSTAG_RMsgNum, 0},
  825.    {UMSTAG_RMsgText, &rMsgText},
  826.    {UMSTAG_RFromName, &rFromName},
  827.    {UMSTAG_RFromAddr, &rFromAddr},
  828.    {UMSTAG_RToName, &rToName},
  829.    {UMSTAG_RToAddr, &rToAddr},
  830.    {UMSTAG_RMsgID, &rMsgID},
  831.    {UMSTAG_RCreationDate, &rCreationDate},
  832.    {UMSTAG_RReferID, &rReferID},
  833.    {UMSTAG_RGroup, &rGroup},
  834.    {UMSTAG_RSubject, &rSubject},
  835.    {UMSTAG_RAttributes, &rAttributes},
  836.    {UMSTAG_RComments, &rComments},
  837.    {UMSTAG_ROrganization, &rOrganization},
  838.    {UMSTAG_RDistribution, &rDistribution},
  839.    {TAG_DONE, 0}
  840.    };
  841.  
  842. VOID Rexx_GETMSG(struct RexxMsg *msg, LONG rxargv[])
  843.    {
  844.    TEXT buff[LEN_NUMBER+1];
  845.    STRPTR varname = NULL;
  846.  
  847.    if (!MyUMSAccount)
  848.       RexxErr(ERR_NO_LOGIN);
  849.    else if (!rxargv[0] && !Lastmsg) /* NUMBER */
  850.       RexxErr(ERR_NO_MSG_READ);
  851.    else
  852.       {
  853.       if (rxargv[17]) /* VAR/K */
  854.          {
  855.          varname = (STRPTR)rxargv[17];
  856.          if (strlen(varname) > LEN_REXXVAR)
  857.             {
  858.             RexxErr(ERR_VARNAME_TOO_LONG);
  859.             return;
  860.             }
  861.          }
  862.  
  863.       if (rxargv[0]) /* NUMBER */
  864.          readTags[0].ti_Data = *(ULONG *)rxargv[0];
  865.       else
  866.          readTags[0].ti_Data = Lastmsg;
  867.  
  868.       if (!UMSReadMsg(MyUMSAccount, &readTags[0]))
  869.          {
  870.          UMSFreeMsg(MyUMSAccount, readTags[0].ti_Data);
  871.  
  872.          RexxErr(ERR_UMS_READ_ERROR);
  873.          }
  874.       else
  875.          {
  876.          if (rxargv[1]) /* MSGNUM/S */
  877.             {
  878.             sprintf(buff, "%ld", Lastmsg);
  879.             RexxOK(buff, varname);
  880.             }
  881.          else if (rxargv[2]) /* MSGTEXT/S */
  882.             RexxOK(rMsgText, varname);
  883.          else if (rxargv[3]) /* FROMNAME/S */
  884.             RexxOK(rFromName, varname);
  885.          else if (rxargv[4]) /* FROMADDR/S */
  886.             RexxOK(rFromAddr, varname);
  887.          else if (rxargv[5]) /* TONAME/S */
  888.             RexxOK(rToName, varname);
  889.          else if (rxargv[6]) /* TOADDR/S */
  890.             RexxOK(rToAddr, varname);
  891.          else if (rxargv[7]) /* MSGID/S */
  892.             RexxOK(rMsgID, varname);
  893.          else if (rxargv[8]) /* CREATIONDATE/S */
  894.             RexxOK(rCreationDate, varname);
  895.          else if (rxargv[9]) /* REFERID/S */
  896.             RexxOK(rReferID, varname);
  897.          else if (rxargv[10]) /* GROUP/S */
  898.             RexxOK(rGroup, varname);
  899.          else if (rxargv[11]) /* SUBJECT/S */
  900.             RexxOK(rSubject, varname);
  901.          else if (rxargv[12]) /* ATTRIBUTES/S */
  902.             RexxOK(rAttributes, varname);
  903.          else if (rxargv[13]) /* COMMENTS/S */
  904.             RexxOK(rComments, varname);
  905.          else if (rxargv[14]) /* ORGANIZATION/S */
  906.             RexxOK(rOrganization, varname);
  907.          else if (rxargv[15]) /* DISTRIBUTION/S */
  908.             RexxOK(rDistribution, varname);
  909.          else if (rxargv[16]) /* ALL/S */
  910.             {
  911.             if (!varname)
  912.                {
  913.                RexxErr(ERR_NO_VARNAME);
  914.                UMSFreeMsg(MyUMSAccount, readTags[0].ti_Data);
  915.                return;
  916.                }
  917.  
  918.             sprintf(buff, "%ld", Lastmsg);
  919.             SetARexxVarName(msg, buff, varname, "MSGNUM");
  920.             SetARexxVarName(msg, rMsgText, varname, "MSGTEXT");
  921.             SetARexxVarName(msg, rFromName, varname, "FROMNAME");
  922.             SetARexxVarName(msg, rFromAddr, varname, "FROMADDR");
  923.             SetARexxVarName(msg, rToName, varname, "TONAME");
  924.             SetARexxVarName(msg, rToAddr, varname, "TOADDR");
  925.             SetARexxVarName(msg, rMsgID, varname, "MSGID");
  926.             SetARexxVarName(msg, rCreationDate, varname, "CREATIONDATE");
  927.             SetARexxVarName(msg, rReferID, varname, "REFERID");
  928.             SetARexxVarName(msg, rGroup, varname, "GROUP");
  929.             SetARexxVarName(msg, rSubject, varname, "SUBJECT");
  930.             SetARexxVarName(msg, rAttributes, varname, "ATTRIBUTES");
  931.             SetARexxVarName(msg, rComments, varname, "COMMENTS");
  932.             SetARexxVarName(msg, rOrganization, varname, "ORGANIZATION");
  933.             SetARexxVarName(msg, rDistribution, varname, "DISTRIBUTION");
  934.             }
  935.  
  936.          UMSFreeMsg(MyUMSAccount, readTags[0].ti_Data);
  937.          }
  938.       }
  939.    }
  940.  
  941. ///
  942.  
  943. /***************************************
  944.  * Rexx-Kommando "GETAREA"             *
  945.  ***************************************
  946.  * I: Parameterstring                  *
  947.  * O: ---                              *
  948.  ***************************************/
  949.  
  950. /// "Rexx_GETAREA"
  951.  
  952. /* PATH,ID/S,AREANAME/S,INFO/S,MBNAME/S,TYPE/S,READLEVEL/S,WRITELEVEL/S,
  953.    EDITLEVEL/S,HOLDNUM/S,HOLDDAYS/S,QOTESTR/S,PQUOTESTR/S,RESENDSTR/S,
  954.    FORWARDSTR/S,ORIGINSTR/S,ALL/S,VAR/K */
  955.  
  956. VOID Rexx_GETAREA(struct RexxMsg *msg, LONG rxargv[])
  957.    {
  958.    TEXT buff[LEN_MAXLINE+1];
  959.    STRPTR varname = NULL;
  960.  
  961.    if (!MyUMSAccount)
  962.       RexxErr(ERR_NO_LOGIN);
  963.    else
  964.       {
  965.       if (rxargv[17]) /* VAR/K */
  966.          {
  967.          varname = (STRPTR)rxargv[17];
  968.          if (strlen(varname) > LEN_REXXVAR)
  969.             {
  970.             RexxErr(ERR_VARNAME_TOO_LONG);
  971.             return;
  972.             }
  973.          }
  974.  
  975.       struct AreaNode *apoint = KMS_LC->Session.CurrentArea;
  976.  
  977.       if (rxargv[0] && !(apoint = ChangeArea((STRPTR)rxargv[0]))) /* NAME */
  978.          {
  979.          RexxErr(ERR_NO_SUCH_AREA);
  980.          return;
  981.          }
  982.  
  983.       if (rxargv[1]) /* ID/S */
  984.          {
  985.          sprintf(buff, "%d", apoint->AreaData.ID);
  986.          RexxOK(buff, varname);
  987.          }
  988.       else if (rxargv[2]) /* AREANAME/S */
  989.          RexxOK(apoint->AreaData.Name, varname);
  990.       else if (rxargv[3]) /* INFO/S */
  991.          RexxOK(apoint->AreaData.Info, varname);
  992.       else if (rxargv[4]) /* MBNAME/S */
  993.          RexxOK(apoint->AreaData.MBName, varname);
  994.       else if (rxargv[5]) /* TYPE/S */
  995.          {
  996.          if (apoint->AreaData.Type & ATYPE_FILES)
  997.             strcpy(buff, "[BINARY] ");
  998.          else if (apoint->AreaData.Type & ATYPE_PRIVATE)
  999.             strcpy(buff, "[MAIL] ");
  1000.          else
  1001.             strcpy(buff, "[NEWS] ");
  1002.          if (apoint->AreaData.Type & ATYPE_GROUP)
  1003.             strcat(buff, "[GROUP]");
  1004.          else
  1005.             strcat(buff, "[NOGROUP]");
  1006.          RexxOK(buff, varname);
  1007.          }
  1008.       else if (rxargv[6]) /* READLEVEL/S */
  1009.          {
  1010.          sprintf(buff, "%d", apoint->AreaData.ReadLevel);
  1011.          RexxOK(buff, varname);
  1012.          }
  1013.       else if (rxargv[7]) /* WRITELEVEL/S */
  1014.          {
  1015.          sprintf(buff, "%d", apoint->AreaData.WriteLevel);
  1016.          RexxOK(buff, varname);
  1017.          }
  1018.       else if (rxargv[8]) /* EDITLEVEL/S */
  1019.          {
  1020.          sprintf(buff, "%d", apoint->AreaData.EditLevel);
  1021.          RexxOK(buff, varname);
  1022.          }
  1023.       else if (rxargv[9]) /* HOLDNUM/S */
  1024.          {
  1025.          sprintf(buff, "%d", apoint->AreaData.HoldNum);
  1026.          RexxOK(buff, varname);
  1027.          }
  1028.       else if (rxargv[10]) /* HOLDDAYS/S */
  1029.          {
  1030.          sprintf(buff, "%d", apoint->AreaData.HoldDays);
  1031.          RexxOK(buff, varname);
  1032.          }
  1033.       else if (rxargv[11]) /* QUOTESTR/S */
  1034.          {
  1035.          sprintf(buff, "%d", apoint->AreaData.QuoteStr);
  1036.          RexxOK(buff, varname);
  1037.          }
  1038.       else if (rxargv[12]) /* PQUOTESTR/S */
  1039.          {
  1040.          sprintf(buff, "%d", apoint->AreaData.PQuoteStr);
  1041.          RexxOK(buff, varname);
  1042.          }
  1043.       else if (rxargv[13]) /* RESENDSTR/S */
  1044.          {
  1045.          sprintf(buff, "%d", apoint->AreaData.ResendStr);
  1046.          RexxOK(buff, varname);
  1047.          }
  1048.       else if (rxargv[14]) /* FORWARDSTR/S */
  1049.          {
  1050.          sprintf(buff, "%d", apoint->AreaData.ForwardStr);
  1051.          RexxOK(buff, varname);
  1052.          }
  1053.       else if (rxargv[15]) /* ORIGINSTR/S */
  1054.          {
  1055.          sprintf(buff, "%d", apoint->AreaData.OriginStr);
  1056.          RexxOK(buff, varname);
  1057.          }
  1058.       else if (rxargv[16]) /* ALL/S */
  1059.          {
  1060.          if (!varname)
  1061.             {
  1062.             RexxErr(ERR_NO_VARNAME);
  1063.             return;
  1064.             }
  1065.  
  1066.          sprintf(buff, "%d", apoint->AreaData.ID);
  1067.          SetARexxVarName(msg, buff, varname, "ID");
  1068.          SetARexxVarName(msg, apoint->AreaData.Name, varname, "AREANAME");
  1069.          SetARexxVarName(msg, apoint->AreaData.Info, varname, "INFO");
  1070.          SetARexxVarName(msg, apoint->AreaData.MBName, varname, "MBNAME");
  1071.          if (apoint->AreaData.Type & ATYPE_FILES)
  1072.             strcpy(buff, "[BINARY] ");
  1073.          else if (apoint->AreaData.Type & ATYPE_PRIVATE)
  1074.             strcpy(buff, "[MAIL] ");
  1075.          else
  1076.             strcpy(buff, "[NEWS] ");
  1077.          if (apoint->AreaData.Type & ATYPE_GROUP)
  1078.             strcat(buff, "[GROUP]");
  1079.          else
  1080.             strcat(buff, "[NOGROUP]");
  1081.          SetARexxVarName(msg, buff, varname, "TYPE");
  1082.          sprintf(buff, "%d", apoint->AreaData.ReadLevel);
  1083.          SetARexxVarName(msg, buff, varname, "READLEVEL");
  1084.          sprintf(buff, "%d", apoint->AreaData.WriteLevel);
  1085.          SetARexxVarName(msg, buff, varname, "WRITELEVEL");
  1086.          sprintf(buff, "%d", apoint->AreaData.EditLevel);
  1087.          SetARexxVarName(msg, buff, varname, "EDITLEVEL");
  1088.          sprintf(buff, "%d", apoint->AreaData.HoldNum);
  1089.          SetARexxVarName(msg, buff, varname, "HOLDNUM");
  1090.          sprintf(buff, "%d", apoint->AreaData.HoldDays);
  1091.          SetARexxVarName(msg, buff, varname, "HOLDDAYS");
  1092.          sprintf(buff, "%d", apoint->AreaData.QuoteStr);
  1093.          SetARexxVarName(msg, buff, varname, "QUOTESTR");
  1094.          sprintf(buff, "%d", apoint->AreaData.PQuoteStr);
  1095.          SetARexxVarName(msg, buff, varname, "PQUOTESTR");
  1096.          sprintf(buff, "%d", apoint->AreaData.ResendStr);
  1097.          SetARexxVarName(msg, buff, varname, "RESENDSTR");
  1098.          sprintf(buff, "%d", apoint->AreaData.ForwardStr);
  1099.          SetARexxVarName(msg, buff, varname, "FORWARDSTR");
  1100.          sprintf(buff, "%d", apoint->AreaData.OriginStr);
  1101.          SetARexxVarName(msg, buff, varname, "ORIGINSTR");
  1102.          }
  1103.       else
  1104.          RexxErr(ERR_INVALID_PARAMS);
  1105.       }
  1106.    }
  1107.  
  1108. ///
  1109.  
  1110. /***************************************
  1111.  * Rexx-Kommando "GETACCESS"           *
  1112.  ***************************************
  1113.  * I: Parameterstring                  *
  1114.  * O: ---                              *
  1115.  ***************************************/
  1116.  
  1117. /// "Rexx_GETACCESS"
  1118.  
  1119. /* AREA/K,VAR/K */
  1120.  
  1121. VOID Rexx_GETACCESS(struct RexxMsg *msg, LONG rxargv[])
  1122.    {
  1123.    TEXT buff[LEN_MAXLINE+1];
  1124.    STRPTR varname = NULL;
  1125.    struct AreaNode *apoint = KMS_LC->Session.CurrentArea;
  1126.    UBYTE curraccess;
  1127.  
  1128.    if (!MyUMSAccount)
  1129.       {
  1130.       RexxErr(ERR_NO_LOGIN);
  1131.       return;
  1132.       }
  1133.  
  1134.    if (rxargv[0])
  1135.       {
  1136.       if (!(apoint = ChangeArea((STRPTR)rxargv[0])))
  1137.          {
  1138.          RexxErr(ERR_NO_SUCH_AREA);
  1139.          return;
  1140.          }
  1141.       }
  1142.  
  1143.    if (rxargv[1])
  1144.       {
  1145.       varname = (STRPTR)rxargv[1];
  1146.       if (strlen(varname) > LEN_REXXVAR)
  1147.          {
  1148.          RexxErr(ERR_VARNAME_TOO_LONG);
  1149.          return;
  1150.          }
  1151.       }
  1152.  
  1153.    curraccess = CheckAccess(apoint);
  1154.  
  1155.    *buff = '\0';
  1156.    if (curraccess & AACC_READ)
  1157.       strcat(buff, "[READ] ");
  1158.    if (curraccess & AACC_WRITE)
  1159.       strcat(buff, "[WRITE] ");
  1160.    if (curraccess & AACC_EDIT)
  1161.       strcat(buff, "[EDIT]");
  1162.    
  1163.    RexxOK(buff, varname);
  1164.    }
  1165.  
  1166. ///
  1167.  
  1168. /***************************************
  1169.  * Rexx-Kommando "INPUTSTR"            *
  1170.  ***************************************
  1171.  * I: Parameterstring                  *
  1172.  * O: ---                              *
  1173.  ***************************************/
  1174.  
  1175. /// "Rexx_INPUTSTR"
  1176.  
  1177. /* PROMPT/K,LENGTH/K/N,DEFTXT/K,CHOICE/K,NUMERIC/S,NOEMPTY/S,
  1178.    CTRLKEYS/S,NOINSERT/S,UPPERCASE/S,AUTOEXIT/S,HIDDEN/S */
  1179.  
  1180. VOID Rexx_INPUTSTR(struct RexxMsg *msg, LONG rxargv[])
  1181.    {
  1182.    TEXT inmerk[LEN_CMDINPUT+1];
  1183.    STRPTR prompt = NULL, excludes = NULL, deftxt = NULL;
  1184.    ULONG length = KMS_LC->Session.CurrentUser->UserData.LineLen;
  1185.    UWORD flags = 0;
  1186.    BOOL modemerk;
  1187.  
  1188.    if (!MyUMSAccount)
  1189.       {
  1190.       RexxErr(ERR_NO_LOGIN);
  1191.       return;
  1192.       }
  1193.  
  1194.    if (rxargv[0]) /* PROMPT/K */
  1195.       prompt = (STRPTR)rxargv[0];
  1196.    if (rxargv[1]) /* LENGTH/K/N */
  1197.       length = *(ULONG *)rxargv[1];
  1198.    if (rxargv[2]) /* DEFTXT/K */
  1199.       {
  1200.       deftxt = (STRPTR)rxargv[2];
  1201.       flags |= INF_DEFBUF;
  1202.       }
  1203.    if (rxargv[3]) /* CHOICE/K */
  1204.       excludes = (STRPTR)rxargv[3];
  1205.    if (rxargv[4]) /* NUMERIC/S */
  1206.       flags |= INF_NUMERIC;
  1207.    if (rxargv[5]) /* NOEMPTY/S */
  1208.       flags |= INF_NOEMPTY;
  1209.    if (rxargv[6]) /* CTRLKEYS/S */
  1210.       flags |= INF_CRSMODE;
  1211.    if (rxargv[7]) /* NOINSERT/S */
  1212.       flags |= INF_NOINSERT;
  1213.    if (rxargv[8]) /* UPPERCASE/S */
  1214.       flags |= INF_UPCASE;
  1215.    if (rxargv[9]) /* AUTOEXIT/S */
  1216.       flags |= INF_FORCECR;
  1217.    if (rxargv[10]) /* HIDDEN/S */
  1218.       flags |= INF_HIDE;
  1219.  
  1220.    if (!(modemerk = KMS_LC->RawMode))
  1221.       {
  1222.       if (IsInteractive(KMS_LC->InHandle))
  1223.          SetMode(KMS_LC->InHandle, 1); // RAW: Modus
  1224.       KMS_LC->RawMode = TRUE;
  1225.       }
  1226.  
  1227.    strcpy(inmerk, KMS_LC->Session.InputBuffer);
  1228.  
  1229.    if (CmdInput(prompt, 0, excludes, deftxt, (UWORD)length, flags) < 0)
  1230.       {
  1231.       if (ShutDown)
  1232.          RexxErr(ERR_SHUTDOWN);
  1233.       else if (Plop)
  1234.          RexxErr(ERR_TIMEOUT);
  1235.       }
  1236.    else
  1237.       RexxOK(KMS_LC->Session.InputBuffer, NULL);
  1238.  
  1239.    strcpy(KMS_LC->Session.InputBuffer, inmerk);
  1240.  
  1241.    if (!modemerk)
  1242.       {
  1243.       if (IsInteractive(KMS_LC->InHandle))
  1244.          SetMode(KMS_LC->InHandle, 0); // CON: Modus
  1245.       KMS_LC->RawMode = FALSE;
  1246.       }
  1247.    }
  1248.  
  1249. ///
  1250.  
  1251. /***************************************
  1252.  * Rexx-Kommando "GETUSER"             *
  1253.  ***************************************
  1254.  * I: Parameterstring                  *
  1255.  * O: ---                              *
  1256.  ***************************************/
  1257.  
  1258. /// "Rexx_GETUSER"
  1259.  
  1260. /* NAME,USERNAME/S,PASSWORD/S,LEVEL/S,LASTCALL/S,CALLS/S,REALNAME/S,
  1261.    STREET/S,CITY/S,PHONE/S,CHARSET/S,FLAGS/S,PROMPT/S,DISKQUOTA/S,
  1262.    PAGELEN/S,LINELEN/S,ACCESSBITS/S,ALL/S,VAR/K */
  1263.  
  1264. VOID Rexx_GETUSER(struct RexxMsg *msg, LONG rxargv[])
  1265.    {
  1266.    TEXT buff[LEN_MAXLINE+1];
  1267.    TEXT timebuff[LEN_MAKETIME+1];
  1268.    STRPTR varname = NULL;
  1269.    struct Userdaten user;
  1270.    struct UserNode *upoint;
  1271.  
  1272.    if (rxargv[18]) /* VAR/K */
  1273.       {
  1274.       varname = (STRPTR)rxargv[18];
  1275.       if (strlen(varname) > LEN_REXXVAR)
  1276.          {
  1277.          RexxErr(ERR_VARNAME_TOO_LONG);
  1278.          return;
  1279.          }
  1280.       }
  1281.  
  1282.    if (rxargv[0] && !(upoint = UserCheck((STRPTR)rxargv[0])))
  1283.       {
  1284.       RexxErr(ERR_NO_SUCH_USER);
  1285.       return;
  1286.       }
  1287.    else if (!rxargv[0])
  1288.       {
  1289.       if ((upoint = KMS_LC->Session.CurrentUser) == &DummyUser)
  1290.          {
  1291.          RexxErr(ERR_NO_LOGIN);
  1292.          return;
  1293.          }
  1294.       }
  1295.  
  1296.    user = upoint->UserData;
  1297.  
  1298.    if (rxargv[1]) /* USERNAME/S */
  1299.       RexxOK(user.Name, varname);
  1300.    else if (rxargv[2]) /* PASSWORD/S */
  1301.       {
  1302.       if (rxargv[0] && strcmp(KMS_LC->Session.CurrentUser->UserData.Name, (STRPTR)rxargv[0]))
  1303.          RexxErr(ERR_ONLY_CURRENT_PWD);
  1304.       else
  1305.          RexxOK(KMS_LC->Session.Password, varname);
  1306.       }
  1307.    else if (rxargv[3]) /* LEVEL/S */
  1308.       {
  1309.       sprintf(buff, "%d", user.Level);
  1310.       RexxOK(buff, varname);
  1311.       }
  1312.    else if (rxargv[4]) /* LASTCALL/S */
  1313.       {
  1314.       MakeTime(timebuff, 0, user.LastCall);
  1315.       RexxOK(timebuff, varname);
  1316.       }
  1317.    else if (rxargv[5]) /* CALLS/S */
  1318.       {
  1319.       sprintf(buff, "%d", user.Calls);
  1320.       RexxOK(buff, varname);
  1321.       }
  1322.    else if (rxargv[6]) /* REALNAME/S */
  1323.       RexxOK(user.RealName, varname);
  1324.    else if (rxargv[7]) /* STREET/S */
  1325.       RexxOK(user.Street, varname);
  1326.    else if (rxargv[8]) /* CITY/S */
  1327.       RexxOK(user.City, varname);
  1328.    else if (rxargv[9]) /* PHONE/S */
  1329.       RexxOK(user.Phone, varname);
  1330.    else if (rxargv[10]) /* CHARSET/S */
  1331.       {
  1332.       sprintf(buff, "%d", user.CharSet);
  1333.       RexxOK(buff, varname);
  1334.       }
  1335.    else if (rxargv[11]) /* FLAGS/S */
  1336.       {
  1337.       if (user.Flags & UF_EMU_ANSI)
  1338.          strcpy(buff, "[ANSI] ");
  1339.       else
  1340.          strcpy(buff, "[TTY] ");
  1341.       if (user.Flags & UF_CLS)
  1342.          strcat(buff, "[CLS] ");
  1343.       else
  1344.          strcat(buff, "[NOCLS] ");
  1345.       if (user.Flags & UF_HEAD_LONG)
  1346.          strcat(buff, "[LONGMSGHEAD] ");
  1347.       else
  1348.          strcat(buff, "[SHORTMSGHEAD] ");
  1349.       if (user.Flags & UF_EDIT_INSERT)
  1350.          strcat(buff, "[INSERT] ");
  1351.       else
  1352.          strcat(buff, "[OVERSTRIKE] ");
  1353.       if (user.Flags & UF_AUTO_LIST)
  1354.          strcat(buff, "[AUTOLIST] ");
  1355.       else
  1356.          strcat(buff, "[NOAUTOLIST] ");
  1357.       if (user.Flags & UF_AUTO_AREALIST)
  1358.          strcat(buff, "[AUTOAREALIST] ");
  1359.       else
  1360.          strcat(buff, "[NOAUTOAREALIST] ");
  1361.       if (user.Flags & UF_RMODE_NEW)
  1362.          strcat(buff, "[READNEW] ");
  1363.       else if (user.Flags & UF_RMODE_SEL)
  1364.          strcat(buff, "[READSEL] ");
  1365.       else if (user.Flags & UF_RMODE_THRD)
  1366.          strcat(buff, "[READTHREAD] ");
  1367.       else
  1368.          strcat(buff, "[READNEXT] ");
  1369.       if (user.Flags & UF_SCREEN_ED)
  1370.          strcat(buff, "[SCREENED] ");
  1371.       else
  1372.          strcat(buff, "[SIMPLEED] ");
  1373.       if (user.Flags & UF_EXTSEND)
  1374.          strcat(buff, "[SENDOPTS] ");
  1375.       else
  1376.          strcat(buff, "[NOSENDOPTS] ");
  1377.       if (user.Flags & UF_PDAT_SECRET)
  1378.          strcat(buff, "[PDATSECRET]");
  1379.       else
  1380.          strcat(buff, "[PDATPUBLIC]");
  1381.       RexxOK(buff, varname);
  1382.       }
  1383.    else if (rxargv[12]) /* PROMPT/S */
  1384.       RexxOK(user.Prompt, varname);
  1385.    else if (rxargv[13]) /* DISKQUOTA/S */
  1386.       {
  1387.       sprintf(buff, "%d", user.Quota);
  1388.       RexxOK(buff, varname);
  1389.       }
  1390.    else if (rxargv[14]) /* PAGELEN/S */
  1391.       {
  1392.       sprintf(buff, "%d", user.PageLen);
  1393.       RexxOK(buff, varname);
  1394.       }
  1395.    else if (rxargv[15]) /* LINELEN/S */
  1396.       {
  1397.       sprintf(buff, "%d", user.LineLen);
  1398.       RexxOK(buff, varname);
  1399.       }
  1400.    else if (rxargv[16]) /* ACCESSBITS/S */
  1401.       {
  1402.       sprintf(buff, "%ld", user.AccessBits);
  1403.       RexxOK(buff, varname);
  1404.       }
  1405.    else if (rxargv[17]) /* ALL/S */
  1406.       {
  1407.       if (!varname)
  1408.          {
  1409.          RexxErr(ERR_NO_VARNAME);
  1410.          return;
  1411.          }
  1412.  
  1413.       SetARexxVarName(msg, user.Name, varname, "USERNAME");
  1414.       if (rxargv[0] && strcmp(KMS_LC->Session.CurrentUser->UserData.Name, (STRPTR)rxargv[0]))
  1415.          SetARexxVarName(msg, "<not available>", varname, "PASSWORD");
  1416.       else
  1417.          SetARexxVarName(msg, KMS_LC->Session.Password, varname, "PASSWORD");
  1418.       sprintf(buff, "%d", user.Level);
  1419.       SetARexxVarName(msg, buff, varname, "LEVEL");
  1420.       MakeTime(timebuff, 0, user.LastCall);
  1421.       SetARexxVarName(msg, timebuff, varname, "LASTCALL");
  1422.       sprintf(buff, "%d", user.Calls);
  1423.       SetARexxVarName(msg, buff, varname, "CALLS");
  1424.       SetARexxVarName(msg, user.RealName, varname, "REALNAME");
  1425.       SetARexxVarName(msg, user.Street, varname, "STREET");
  1426.       SetARexxVarName(msg, user.City, varname, "CITY");
  1427.       SetARexxVarName(msg, user.Phone, varname, "PHONE");
  1428.       sprintf(buff, "%d", user.CharSet);
  1429.       SetARexxVarName(msg, buff, varname, "CHARSET");
  1430.       if (user.Flags & UF_EMU_ANSI)
  1431.          strcpy(buff, "[ANSI] ");
  1432.       else
  1433.          strcpy(buff, "[TTY] ");
  1434.       if (user.Flags & UF_CLS)
  1435.          strcat(buff, "[CLS] ");
  1436.       else
  1437.          strcat(buff, "[NOCLS] ");
  1438.       if (user.Flags & UF_HEAD_LONG)
  1439.          strcat(buff, "[LONGMSGHEAD] ");
  1440.       else
  1441.          strcat(buff, "[SHORTMSGHEAD] ");
  1442.       if (user.Flags & UF_EDIT_INSERT)
  1443.          strcat(buff, "[INSERT] ");
  1444.       else
  1445.          strcat(buff, "[OVERSTRIKE] ");
  1446.       if (user.Flags & UF_AUTO_LIST)
  1447.          strcat(buff, "[AUTOLIST] ");
  1448.       else
  1449.          strcat(buff, "[NOAUTOLIST] ");
  1450.       if (user.Flags & UF_AUTO_AREALIST)
  1451.          strcat(buff, "[AUTOAREALIST] ");
  1452.       else
  1453.          strcat(buff, "[NOAUTOAREALIST] ");
  1454.       if (user.Flags & UF_RMODE_NEW)
  1455.          strcat(buff, "[READNEW] ");
  1456.       else if (user.Flags & UF_RMODE_SEL)
  1457.          strcat(buff, "[READSEL] ");
  1458.       else if (user.Flags & UF_RMODE_THRD)
  1459.          strcat(buff, "[READTHREAD] ");
  1460.       else
  1461.          strcat(buff, "[READNEXT] ");
  1462.       if (user.Flags & UF_SCREEN_ED)
  1463.          strcat(buff, "[SCREENED] ");
  1464.       else
  1465.          strcat(buff, "[SIMPLEED] ");
  1466.       if (user.Flags & UF_EXTSEND)
  1467.          strcat(buff, "[SENDOPTS] ");
  1468.       else
  1469.          strcat(buff, "[NOSENDOPTS] ");
  1470.       if (user.Flags & UF_PDAT_SECRET)
  1471.          strcat(buff, "[PDATSECRET]");
  1472.       else
  1473.          strcat(buff, "[PDATPUBLIC]");
  1474.       SetARexxVarName(msg, buff, varname, "FLAGS");
  1475.       SetARexxVarName(msg, user.Prompt, varname, "PROMPT");
  1476.       sprintf(buff, "%d", user.Quota);
  1477.       SetARexxVarName(msg, buff, varname, "DISKQUOTA");
  1478.       sprintf(buff, "%d", user.PageLen);
  1479.       SetARexxVarName(msg, buff, varname, "PAGELEN");
  1480.       sprintf(buff, "%d", user.LineLen);
  1481.       SetARexxVarName(msg, buff, varname, "LINELEN");
  1482.       sprintf(buff, "%ld", user.AccessBits);
  1483.       SetARexxVarName(msg, buff, varname, "ACCESSBITS");
  1484.       }
  1485.    }
  1486.  
  1487. ///
  1488.  
  1489. /***************************************
  1490.  * Rexx-Kommando "SETUSER"             *
  1491.  ***************************************
  1492.  * I: Parameterstring                  *
  1493.  * O: ---                              *
  1494.  ***************************************/
  1495.  
  1496. /// "Rexx_SETUSER"
  1497.  
  1498. /* NAME,USERNAME/S,PASSWORD/S,LEVEL/S,LASTCALL/S,CALLS/S,REALNAME/S,
  1499.    STREET/S,CITY/S,PHONE/S,CHARSET/S,FLAGS/S,PROMPT/S,DISKQUOTA/S,
  1500.    PAGELEN/S,LINELEN/S,ACCESSBITS/S,ALL/S,VALUE/K/A */
  1501.  
  1502. VOID Rexx_SETUSER(struct RexxMsg *msg, LONG rxargv[])
  1503.    {
  1504.    STRPTR buff;
  1505.    STRPTR varname = NULL;
  1506.    struct Userdaten user;
  1507.    struct UserNode *upoint;
  1508.    TEXT pwd[LEN_PASSWORD+1];
  1509.    BOOL currentuser = FALSE;
  1510.    BOOL pwdchange = FALSE;
  1511.  
  1512.    if (rxargv[0] && !(upoint = UserCheck((STRPTR)rxargv[0])))
  1513.       {
  1514.       RexxErr(ERR_NO_SUCH_USER);
  1515.       return;
  1516.       }
  1517.    else if (!rxargv[0])
  1518.       {
  1519.       if ((upoint = KMS_LC->Session.CurrentUser) == &DummyUser)
  1520.          {
  1521.          RexxErr(ERR_NO_LOGIN);
  1522.          return;
  1523.          }
  1524.       }
  1525.  
  1526.    user = upoint->UserData;
  1527.  
  1528.    if (!strcmp(user.Name, KMS_LC->Session.CurrentUser->UserData.Name))
  1529.       currentuser = TRUE;
  1530.  
  1531.    if (rxargv[1]) /* USERNAME/S */
  1532.       {
  1533.       strncpy(user.Name, (STRPTR)rxargv[18], LEN_USERNAME);
  1534.       user.Name[LEN_USERNAME] = '\0';
  1535.       ConvertSpace(user.Name);
  1536.       }
  1537.    else if (rxargv[2]) /* REALNAME/S */
  1538.       {
  1539.       strncpy(user.RealName, (STRPTR)rxargv[18], LEN_REALNAME);
  1540.       user.RealName[LEN_REALNAME] = '\0';
  1541.       }
  1542.    else if (rxargv[3]) /* PASSWORD/S */
  1543.       {
  1544.       if (strlen((STRPTR)rxargv[18]) > LEN_PASSWORD)
  1545.          {
  1546.          RexxErr(ERR_INVALID_PARAMS);
  1547.          return;
  1548.          }
  1549.  
  1550.       UMSWriteConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1551.                                         UMSTAG_CfgName, "PASSWORD",
  1552.                                         UMSTAG_CfgData, rxargv[18],
  1553.                                         TAG_DONE);
  1554.       strcpy(pwd, (STRPTR)rxargv[18]);
  1555.       pwdchange = TRUE;
  1556.       }
  1557.    else if (rxargv[4]) /* LEVEL/S */
  1558.       user.Level = *(UWORD *)rxargv[18];
  1559.    else if (rxargv[5]) /* LASTCALL/S */
  1560.       user.LastCall = *(ULONG *)rxargv[18];
  1561.    else if (rxargv[6]) /* CALLS/S */
  1562.       user.Calls = *(UWORD *)rxargv[18];
  1563.    else if (rxargv[7]) /* STREET/S */
  1564.       {
  1565.       strncpy(user.Street, (STRPTR)rxargv[18], LEN_STREET);
  1566.       user.Street[LEN_STREET] = '\0';
  1567.       }
  1568.    else if (rxargv[8]) /* CITY/S */
  1569.       {
  1570.       strncpy(user.City, (STRPTR)rxargv[18], LEN_CITY);
  1571.       user.City[LEN_CITY] = '\0';
  1572.       }
  1573.    else if (rxargv[9]) /* PHONE/S */
  1574.       {
  1575.       strncpy(user.Phone, (STRPTR)rxargv[18], LEN_PHONE);
  1576.       user.Phone[LEN_PHONE] = '\0';
  1577.       }
  1578.    else if (rxargv[10]) /* CHARSET/S */
  1579.       user.CharSet = *(UBYTE *)rxargv[18];
  1580.    else if (rxargv[11]) /* FLAGS/S */
  1581.       {
  1582.       if (strstr((STRPTR)rxargv[18], "[ANSI]"))
  1583.          user.Flags |= UF_EMU_ANSI;
  1584.       if (strstr((STRPTR)rxargv[18], "[TTY]"))
  1585.          user.Flags &= ~UF_EMU_ANSI;
  1586.       if (strstr((STRPTR)rxargv[18], "[CLS]"))
  1587.          user.Flags |= UF_CLS;
  1588.       if (strstr((STRPTR)rxargv[18], "[NOCLS]"))
  1589.          user.Flags &= ~UF_CLS;
  1590.       if (strstr((STRPTR)rxargv[18], "[LONGMSGHEAD]"))
  1591.          user.Flags |= UF_HEAD_LONG;
  1592.       if (strstr((STRPTR)rxargv[18], "[SHORTMSGHEAD]"))
  1593.          user.Flags &= ~UF_HEAD_LONG;
  1594.       if (strstr((STRPTR)rxargv[18], "[INSERT]"))
  1595.          user.Flags |= UF_EDIT_INSERT;
  1596.       if (strstr((STRPTR)rxargv[18], "[OVERSTRIKE]"))
  1597.          user.Flags &= ~UF_EDIT_INSERT;
  1598.       if (strstr((STRPTR)rxargv[18], "[AUTOLIST]"))
  1599.          user.Flags |= UF_AUTO_LIST;
  1600.       if (strstr((STRPTR)rxargv[18], "[NOAUTOLIST]"))
  1601.          user.Flags &= ~UF_AUTO_LIST;
  1602.       if (strstr((STRPTR)rxargv[18], "[AUTOAREALIST]"))
  1603.          user.Flags |= UF_AUTO_AREALIST;
  1604.       if (strstr((STRPTR)rxargv[18], "[NOAUTOAREALIST]"))
  1605.          user.Flags &= ~UF_AUTO_AREALIST;
  1606.       if (strstr((STRPTR)rxargv[18], "[READNEW]"))
  1607.          {
  1608.          user.Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  1609.          user.Flags |= UF_RMODE_NEW;
  1610.          }
  1611.       else if (strstr((STRPTR)rxargv[18], "[READSEL]"))
  1612.          {
  1613.          user.Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  1614.          user.Flags |= UF_RMODE_SEL;
  1615.          }
  1616.       else if (strstr((STRPTR)rxargv[18], "[READTHREAD]"))
  1617.          {
  1618.          user.Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  1619.          user.Flags |= UF_RMODE_THRD;
  1620.          }
  1621.       else if (strstr((STRPTR)rxargv[18], "[READNEXT]"))
  1622.          user.Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  1623.       if (strstr((STRPTR)rxargv[18], "[SCREENED]"))
  1624.          user.Flags |= UF_SCREEN_ED;
  1625.       if (strstr((STRPTR)rxargv[18], "[SIMPLEED]"))
  1626.          user.Flags &= ~UF_SCREEN_ED;
  1627.       if (strstr((STRPTR)rxargv[18], "[SENDOPTS]"))
  1628.          user.Flags |= UF_EXTSEND;
  1629.       if (strstr((STRPTR)rxargv[18], "[NOSENDOPTS]"))
  1630.          user.Flags &= ~UF_EXTSEND;
  1631.       if (strstr((STRPTR)rxargv[18], "[PDATSECRET]"))
  1632.          user.Flags |= UF_PDAT_SECRET;
  1633.       if (strstr((STRPTR)rxargv[18], "[PDATPUBLIC]"))
  1634.          user.Flags &= ~UF_PDAT_SECRET;
  1635.       }
  1636.    else if (rxargv[12]) /* PROMPT/S */
  1637.       {
  1638.       strncpy(user.Prompt, (STRPTR)rxargv[18], LEN_UPROMPT);
  1639.       user.Prompt[LEN_UPROMPT] = '\0';
  1640.       }
  1641.    else if (rxargv[13]) /* DISKQUOTA/S */
  1642.       user.Quota = *(UWORD *)rxargv[18];
  1643.    else if (rxargv[14]) /* PAGELEN/S */
  1644.       user.PageLen = *(UBYTE *)rxargv[18];
  1645.    else if (rxargv[15]) /* LINELEN/S */
  1646.       user.LineLen = *(UBYTE *)rxargv[18];
  1647.    else if (rxargv[16]) /* ACCESSBITS/S */
  1648.       user.AccessBits = *(ULONG *)rxargv[18];
  1649.    else if (rxargv[17]) /* ALL/S */
  1650.       {
  1651.       varname = (STRPTR)rxargv[18];
  1652.       if (strlen(varname) > LEN_REXXVAR)
  1653.          {
  1654.          RexxErr(ERR_VARNAME_TOO_LONG);
  1655.          return;
  1656.          }
  1657.  
  1658.       ReadUserStem(&user, msg, varname);
  1659.       if (GetARexxVarName(msg, &buff, varname, "PASSWORD"))
  1660.          {
  1661.          if (strlen(buff) > LEN_PASSWORD)
  1662.             {
  1663.             RexxErr(ERR_INVALID_PARAMS);
  1664.             return;
  1665.             }
  1666.  
  1667.          UMSWriteConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1668.                                            UMSTAG_CfgName, "PASSWORD",
  1669.                                            UMSTAG_CfgData, buff,
  1670.                                            TAG_DONE);
  1671.          strcpy(pwd, buff);
  1672.          pwdchange = TRUE;
  1673.          }
  1674.       }
  1675.  
  1676.    Forbid();
  1677.    upoint->UserData = user;
  1678.    Permit();
  1679.  
  1680.    if (currentuser)
  1681.       {
  1682.       KMS_LC->Session.CurrentAccess = CheckAccess(KMS_LC->Session.CurrentArea);
  1683.       if (pwdchange)
  1684.          strcpy(KMS_LC->Session.Password, pwd);
  1685.       }
  1686.    }
  1687.  
  1688. ///
  1689.  
  1690. /***************************************
  1691.  * Rexx-Kommando "ADDUSER"             *
  1692.  ***************************************
  1693.  * I: Parameterstring                  *
  1694.  * O: ---                              *
  1695.  ***************************************/
  1696.  
  1697. /// "Rexx_ADDUSER"
  1698.  
  1699. /* VAR/K/A */
  1700.  
  1701. VOID Rexx_ADDUSER(struct RexxMsg *msg, LONG rxargv[])
  1702.    {
  1703.    struct UserNode *ulock;
  1704.    struct Userdaten user;
  1705.    STRPTR varname, varbuff;
  1706.  
  1707.    varname = (STRPTR)rxargv[0];
  1708.    if (strlen(varname) > LEN_REXXVAR)
  1709.       {
  1710.       RexxErr(ERR_VARNAME_TOO_LONG);
  1711.       return;
  1712.       }
  1713.  
  1714.    InitUser(&user);
  1715.  
  1716.    ReadUserStem(&user, msg, varname);
  1717.  
  1718.    if (strlen(user.Name))
  1719.       {
  1720.       if (ulock = UserCheck(user.Name))
  1721.          {
  1722.          RexxErr(ERR_USER_EXISTS);
  1723.          return;
  1724.          }
  1725.       }
  1726.    else
  1727.       {
  1728.       RexxErr(ERR_USER_NOT_CREATED);
  1729.       return;
  1730.       }
  1731.  
  1732.    if (!strlen(user.RealName))
  1733.       {
  1734.       RexxErr(ERR_USER_NOT_CREATED);
  1735.       return;
  1736.       }
  1737.  
  1738.    TakeUSem(TRUE);
  1739.    if (ulock = InsertUser())
  1740.       {
  1741.       DropUSem();
  1742.  
  1743.       ulock->UserData = user;
  1744.  
  1745.       /* UMS-User kreieren */
  1746.  
  1747.       if (!AddUMSUser(ulock))
  1748.          {
  1749.          DeleteUser(ulock);
  1750.  
  1751.          RexxErr(ERR_USER_NOT_CREATED);
  1752.          return;
  1753.          }
  1754.       
  1755.       /* User-Directory anlegen */
  1756.  
  1757.       if (!CreateUserDir(ulock))
  1758.          {
  1759.          DelUMSUser(ulock);
  1760.  
  1761.          DeleteUser(ulock);
  1762.  
  1763.          RexxErr(ERR_USER_NOT_CREATED);
  1764.          return;
  1765.          }
  1766.  
  1767.       if (GetARexxVarName(msg, &varbuff, varname, "PASSWORD"))
  1768.          {
  1769.          if (strlen(varbuff) > LEN_PASSWORD)
  1770.             {
  1771.             DeleteUser(ulock);
  1772.             RexxErr(ERR_INVALID_PARAMS);
  1773.             return;
  1774.             }
  1775.  
  1776.          UMSWriteConfigTags(SysUMSAccount, UMSTAG_CfgUser, user.RealName,
  1777.                                            UMSTAG_CfgName, "PASSWORD",
  1778.                                            UMSTAG_CfgData, varbuff,
  1779.                                            TAG_DONE);
  1780.          }
  1781.       }
  1782.    else
  1783.       {
  1784.       DropUSem();
  1785.       RexxErr(ERR_USER_NOT_CREATED);
  1786.       return;
  1787.       }
  1788.    }
  1789.  
  1790. ///
  1791.  
  1792. /***************************************
  1793.  * Rexx-Kommando "KMSEXEC"             *
  1794.  ***************************************
  1795.  * I: Parameterstring                  *
  1796.  * O: ---                              *
  1797.  ***************************************/
  1798.  
  1799. /// "Rexx_KMSEXEC"
  1800.  
  1801. /* COMMAND/F */
  1802.  
  1803. VOID Rexx_KMSEXEC(struct RexxMsg *msg, LONG rxargv[])
  1804.    {
  1805.    STRPTR inbuff, inmerk;
  1806.    BOOL modemerk;
  1807.    UWORD inzeig = 0;
  1808.  
  1809.    /* KMS-Befehl ausführen */
  1810.  
  1811.    BOOL keepgoing = TRUE;
  1812.  
  1813.    inbuff = malloc(LEN_CMDINPUT+1);
  1814.    if (!inbuff)
  1815.       {
  1816.       RexxErr(ERR_OUT_OF_MEMORY);
  1817.       return;
  1818.       }
  1819.    inmerk = malloc(LEN_CMDINPUT+1);
  1820.    if (!inmerk)
  1821.       {
  1822.       RexxErr(ERR_OUT_OF_MEMORY);
  1823.       free(inbuff);
  1824.       return;
  1825.       }
  1826.  
  1827.    strncpy(inbuff, (STRPTR)rxargv[0], LEN_CMDINPUT);
  1828.    inbuff[LEN_CMDINPUT] = '\0';
  1829.  
  1830.    if (!(modemerk = KMS_LC->RawMode))
  1831.       {
  1832.       if (IsInteractive(KMS_LC->InHandle))
  1833.          SetMode(KMS_LC->InHandle, 1); // RAW: Modus
  1834.       KMS_LC->RawMode = TRUE;
  1835.       }
  1836.  
  1837.    strcpy(inmerk, KMS_LC->Session.InputBuffer);
  1838.  
  1839.    do
  1840.       {
  1841.       inzeig = CmdParse(inbuff, inzeig);
  1842.       
  1843.       if (CmdArgC)
  1844.          keepgoing = CmdExecute(atoi(CmdArgV[0]));
  1845.  
  1846.       } while(inzeig && keepgoing);
  1847.    
  1848.    strcpy(KMS_LC->Session.InputBuffer, inmerk);
  1849.  
  1850.    if (!modemerk)
  1851.       {
  1852.       if (IsInteractive(KMS_LC->InHandle))
  1853.          SetMode(KMS_LC->InHandle, 0); // CON: Modus
  1854.       KMS_LC->RawMode = FALSE;
  1855.       }
  1856.    
  1857.    if (inbuff)
  1858.       free(inbuff);
  1859.    if (inmerk)
  1860.       free(inmerk);
  1861.  
  1862.    if (!keepgoing)
  1863.       Plop = PLOP_LOGOUT;
  1864.  
  1865.    KMS_LC->Session.Refresh = TRUE;
  1866.    }
  1867.  
  1868. ///
  1869.  
  1870. /***************************************
  1871.  * Rexx-Kommando "LOGENTRY"            *
  1872.  ***************************************
  1873.  * I: Parameterstring                  *
  1874.  * O: ---                              *
  1875.  ***************************************/
  1876.  
  1877. /// Rexx_LOGENTRY
  1878.  
  1879. /* TEXT/F */
  1880.  
  1881. VOID Rexx_LOGENTRY(struct RexxMsg *msg, LONG rxargv[])
  1882.    {
  1883.    LogEntry((STRPTR)rxargv[0]);
  1884.    }
  1885.  
  1886. ///
  1887.  
  1888. /***************************************
  1889.  * Rexx-Kommando "SETCONMODE"          *
  1890.  ***************************************
  1891.  * I: Parameterstring                  *
  1892.  * O: ---                              *
  1893.  ***************************************/
  1894.  
  1895. /// "Rexx_SETCONMODE"
  1896.  
  1897. /* RAW/S,COOKED/S */
  1898.  
  1899. VOID Rexx_SETCONMODE(struct RexxMsg *msg, LONG rxargv[])
  1900.    {
  1901.    if (rxargv[0]) /* RAW/S */
  1902.       {
  1903.       if (IsInteractive(KMS_LC->InHandle))
  1904.          SetMode(KMS_LC->InHandle, 1);
  1905.       KMS_LC->RawMode = TRUE;
  1906.       }
  1907.    else if (rxargv[1]) /* CON/S */
  1908.       {
  1909.       if (IsInteractive(KMS_LC->InHandle))
  1910.          SetMode(KMS_LC->InHandle, 0);
  1911.       KMS_LC->RawMode = FALSE;
  1912.       }
  1913.    }
  1914.  
  1915. ///
  1916.  
  1917. /***************************************
  1918.  * Rexx-Kommando "GETCONFIG"           *
  1919.  ***************************************
  1920.  * I: Rexxmsg, Parameter, argc, argv   *
  1921.  * O: ---                              *
  1922.  ***************************************/
  1923.  
  1924. /// "Rexx_GETCONFIG"
  1925.  
  1926. /* DATDIR/S,TEXTDIR/S,REXXDIR/S,USERDIR/S,LOGDIR/S,BINDIR/S,DOORDIR/S,
  1927.    TEMPDIR/S,ACCBITS/S,ALL/S,VAR/K */
  1928.  
  1929. VOID Rexx_GETCONFIG(struct RexxMsg *msg, LONG rxargv[])
  1930.    {
  1931.    STRPTR varname = NULL;
  1932.  
  1933.    if (rxargv[10]) /* VAR/K */
  1934.       {
  1935.       varname = (STRPTR)rxargv[10];
  1936.       if (strlen(varname) > LEN_REXXVAR)
  1937.          {
  1938.          RexxErr(ERR_VARNAME_TOO_LONG);
  1939.          return;
  1940.          }
  1941.       }
  1942.  
  1943.    if (rxargv[0]) /* DATDIR/S */
  1944.       RexxOK(KMSBase->DatDir, varname);
  1945.    else if (rxargv[1]) /* TEXTDIR/S */
  1946.       RexxOK(KMSBase->TxtDir, varname);
  1947.    else if (rxargv[2]) /* REXXDIR/S */
  1948.       RexxOK(KMSBase->RexxDir, varname);
  1949.    else if (rxargv[3]) /* USERDIR/S */
  1950.       RexxOK(KMSBase->UserDir, varname);
  1951.    else if (rxargv[4]) /* LOGDIR/S */
  1952.       RexxOK(KMSBase->LogDir, varname);
  1953.    else if (rxargv[5]) /* BINDIR/S */
  1954.       RexxOK(KMSBase->BinDir, varname);
  1955.    else if (rxargv[6]) /* DOORDIR/S */
  1956.       RexxOK(KMSBase->DoorDir, varname);
  1957.    else if (rxargv[7]) /* TEMPDIR/S */
  1958.       RexxOK(KMSBase->TempDir, varname);
  1959.    else if (rxargv[8]) /* ACCBITS/S */
  1960.       {
  1961.       UBYTE count;
  1962.  
  1963.       if (!varname)
  1964.          {
  1965.          RexxErr(ERR_NO_VARNAME);
  1966.          return;
  1967.          }
  1968.  
  1969.       SetARexxVarNum(msg, "32", varname, 0);
  1970.       for(count = 0; count < 32; count++)
  1971.          SetARexxVarNum(msg, KMSBase->AccBitNames[count], varname, count+1);
  1972.       }
  1973.    else if (rxargv[9]) /* ALL/S */
  1974.       {
  1975.       UBYTE count;
  1976.  
  1977.       if (!varname)
  1978.          {
  1979.          RexxErr(ERR_NO_VARNAME);
  1980.          return;
  1981.          }
  1982.  
  1983.       SetARexxVarName(msg, KMSBase->DatDir, varname, "DATDIR");
  1984.       SetARexxVarName(msg, KMSBase->TxtDir, varname, "TEXTDIR");
  1985.       SetARexxVarName(msg, KMSBase->RexxDir, varname, "REXXDIR");
  1986.       SetARexxVarName(msg, KMSBase->UserDir, varname, "USERDIR");
  1987.       SetARexxVarName(msg, KMSBase->LogDir, varname, "LOGDIR");
  1988.       SetARexxVarName(msg, KMSBase->BinDir, varname, "BINDIR");
  1989.       SetARexxVarName(msg, KMSBase->DoorDir, varname, "DOORDIR");
  1990.       SetARexxVarName(msg, KMSBase->TempDir, varname, "TEMPDIR");
  1991.  
  1992.       SetARexxVarNum(msg, "32", varname, 0);
  1993.       for(count = 0; count < 32; count++)
  1994.          SetARexxVarNum(msg, KMSBase->AccBitNames[count], varname, count+1);
  1995.       }
  1996.    }
  1997.  
  1998. ///
  1999.  
  2000. /***************************************
  2001.  * Rexx-Kommando "GETSESSION"          *
  2002.  ***************************************
  2003.  * I: Rexxmsg, Parameter, argc, argv   *
  2004.  * O: ---                              *
  2005.  ***************************************/
  2006.  
  2007. /// "Rexx_GETSESSION"
  2008.  
  2009. /* PID/S,USERNAME/S,LOGINTIME/S,PRIVDIR/S,DEVICE/S,SERDEV/S,SERUNIT/S,
  2010.    BPS/S,ALL/S,VAR/K */
  2011.  
  2012. VOID Rexx_GETSESSION(struct RexxMsg *msg, LONG rxargv[])
  2013.    {
  2014.    TEXT buff[LEN_MAXLINE+1];
  2015.    TEXT dosbuff[LEN_DOSPATH+1];
  2016.    TEXT timebuff[LEN_MAKETIME+1];
  2017.    STRPTR varname = NULL;
  2018.  
  2019.    if (rxargv[9]) /* VAR/K */
  2020.       {
  2021.       varname = (STRPTR)rxargv[9];
  2022.       if (strlen(varname) > LEN_REXXVAR)
  2023.          {
  2024.          RexxErr(ERR_VARNAME_TOO_LONG);
  2025.          return;
  2026.          }
  2027.       }
  2028.  
  2029.    if (rxargv[0]) /* PID/S */
  2030.       {
  2031.       sprintf(buff, "%d", KMS_LC->ID);
  2032.       RexxOK(buff, varname);
  2033.       }
  2034.    else if (rxargv[1]) /* USERNAME/S */
  2035.       {
  2036.       if (!MyUMSAccount)
  2037.          RexxOK("", varname);
  2038.       else
  2039.          RexxOK(KMS_LC->Session.CurrentUser->UserData.Name, varname);
  2040.       }
  2041.    else if (rxargv[2]) /* LOGINTIME/S */
  2042.       {
  2043.       if (!MyUMSAccount)
  2044.          RexxOK("", varname);
  2045.       else
  2046.          {
  2047.          MakeTime(timebuff, 0, KMS_LC->Session.LoginTime);
  2048.          RexxOK(timebuff, varname);
  2049.          }
  2050.       }
  2051.    else if (rxargv[3]) /* PRIVDIR/S */
  2052.       {
  2053.       if (!MyUMSAccount)
  2054.          RexxOK("", varname);
  2055.       else
  2056.          {
  2057.          strcpy(dosbuff, KMSBase->UserDir);
  2058.          strcat(dosbuff, KMS_LC->Session.CurrentUser->UserData.Name);
  2059.          ConvertSpace(dosbuff);
  2060.          RexxOK(dosbuff, varname);
  2061.          }
  2062.       }
  2063.    else if (rxargv[4]) /* DEVICE/S */
  2064.       {
  2065.       if (KMS_LC->Device & DEV_CONSOLE)
  2066.          RexxOK("CONSOLE", varname);
  2067.       else
  2068.          RexxOK("REMOTE", varname);
  2069.       }
  2070.    else if (rxargv[5]) /* SERDEV/S */
  2071.       {
  2072.       RexxOK(KMS_LC->SerDevice, varname);
  2073.       }
  2074.    else if (rxargv[6]) /* SERUNIT/S */
  2075.       {
  2076.       sprintf(buff, "%d", KMS_LC->SerUnit);
  2077.       RexxOK(buff, varname);
  2078.       }
  2079.    else if (rxargv[7]) /* BPS/S */
  2080.       {
  2081.       sprintf(buff, "%ld", KMS_LC->Session.LineSpeed);
  2082.       RexxOK(buff, varname);
  2083.       }
  2084.    else if (rxargv[8]) /* ALL/S */
  2085.       {
  2086.       if (!varname)
  2087.          {
  2088.          RexxErr(ERR_NO_VARNAME);
  2089.          return;
  2090.          }
  2091.  
  2092.       sprintf(buff, "%d", KMS_LC->ID);
  2093.       SetARexxVarName(msg, buff, varname, "PID");
  2094.  
  2095.       if (!MyUMSAccount)
  2096.          {
  2097.          SetARexxVarName(msg, "", varname, "USERNAME");
  2098.          SetARexxVarName(msg, "", varname, "PRIVDIR");
  2099.          SetARexxVarName(msg, "", varname, "LOGINTIME");
  2100.          }
  2101.       else
  2102.          {
  2103.          SetARexxVarName(msg, KMS_LC->Session.CurrentUser->UserData.Name, varname, "USERNAME");
  2104.          MakeTime(timebuff, 0, KMS_LC->Session.LoginTime);
  2105.          SetARexxVarName(msg, timebuff, varname, "LOGINTIME");
  2106.          strcpy(dosbuff, KMSBase->UserDir);
  2107.          strcat(dosbuff, KMS_LC->Session.CurrentUser->UserData.Name);
  2108.          ConvertSpace(dosbuff);
  2109.          SetARexxVarName(msg, dosbuff, varname, "PRIVDIR");
  2110.          }
  2111.  
  2112.       if (KMS_LC->Device & DEV_CONSOLE)
  2113.          SetARexxVarName(msg, "CONSOLE", varname, "DEVICE");
  2114.       else
  2115.          SetARexxVarName(msg, "REMOTE", varname, "DEVICE");
  2116.  
  2117.       SetARexxVarName(msg, KMS_LC->SerDevice, varname, "SERDEV");
  2118.  
  2119.       sprintf(buff, "%d", KMS_LC->SerUnit);
  2120.       SetARexxVarName(msg, buff, varname, "SERUNIT");
  2121.       
  2122.       sprintf(buff, "%ld", KMS_LC->Session.LineSpeed);
  2123.       SetARexxVarName(msg, buff, varname, "BPS");
  2124.       }
  2125.    }
  2126.  
  2127. ///
  2128.  
  2129. /***************************************
  2130.  * Rexx-Kommando "GETFTP"              *
  2131.  ***************************************
  2132.  * I: Rexxmsg, Parameter, argc, argv   *
  2133.  * O: ---                              *
  2134.  ***************************************/
  2135.  
  2136. /// "Rexx_GETFTP"
  2137.  
  2138. /* VAR/K/A */
  2139.  
  2140. VOID Rexx_GETFTP(struct RexxMsg *msg, LONG rxargv[])
  2141.    {
  2142.    TEXT cfgstring[20];
  2143.    UBYTE prot;
  2144.    STRPTR des, lib, opt;
  2145.    STRPTR varname = NULL;
  2146.    BOOL modemerk;
  2147.  
  2148.    varname = (STRPTR)rxargv[0];
  2149.    if (strlen(varname) > LEN_REXXVAR)
  2150.       {
  2151.       RexxErr(ERR_VARNAME_TOO_LONG);
  2152.       return;
  2153.       }
  2154.  
  2155.    if (!(modemerk = KMS_LC->RawMode))
  2156.       {
  2157.       if (IsInteractive(KMS_LC->InHandle))
  2158.          SetMode(KMS_LC->InHandle, 1); // RAW: Modus
  2159.       KMS_LC->RawMode = TRUE;
  2160.       }
  2161.  
  2162.    if (prot = ProtSelect(TRUE))
  2163.       {
  2164.       sprintf(cfgstring, "KMS.xprdescrip%d", prot);
  2165.       des = UMSReadConfigTags(SysUMSAccount, UMSTAG_CfgName, cfgstring, TAG_DONE);
  2166.       sprintf(cfgstring, "KMS.xprlibrary%d", prot);
  2167.       lib = UMSReadConfigTags(SysUMSAccount, UMSTAG_CfgName, cfgstring, TAG_DONE);
  2168.       sprintf(cfgstring, "KMS.xproptions%d", prot);
  2169.       opt = UMSReadConfigTags(SysUMSAccount, UMSTAG_CfgName, cfgstring, TAG_DONE);
  2170.  
  2171.       SetARexxVarName(msg, des, varname, "DESCRIPTION");
  2172.       SetARexxVarName(msg, lib, varname, "LIBRARY");
  2173.       SetARexxVarName(msg, opt, varname, "OPTIONS");
  2174.  
  2175.       if (des)
  2176.          UMSFreeConfig(SysUMSAccount, des);
  2177.       if (lib)
  2178.          UMSFreeConfig(SysUMSAccount, lib);
  2179.       if (opt)
  2180.          UMSFreeConfig(SysUMSAccount, opt);
  2181.       }
  2182.    else
  2183.       {
  2184.       SetARexxVarName(msg, "", varname, "DESCRIPTION");
  2185.       SetARexxVarName(msg, "", varname, "LIBRARY");
  2186.       SetARexxVarName(msg, "", varname, "OPTIONS");
  2187.       }
  2188.  
  2189.    if (!modemerk)
  2190.       {
  2191.       if (IsInteractive(KMS_LC->InHandle))
  2192.          SetMode(KMS_LC->InHandle, 0); // CON: Modus
  2193.       KMS_LC->RawMode = FALSE;
  2194.       }
  2195.    }
  2196.  
  2197. ///
  2198.  
  2199. /***************************************
  2200.  * Rexx-Kommando "GETAREALIST"         *
  2201.  ***************************************
  2202.  * I: Rexxmsg, Parameter, argc, argv   *
  2203.  * O: ---                              *
  2204.  ***************************************/
  2205.  
  2206. /// "Rexx_GETAREALIST"
  2207.  
  2208. /* PATH,VAR/K/A */
  2209.  
  2210. VOID Rexx_GETAREALIST(struct RexxMsg *msg, LONG rxargv[])
  2211.    {
  2212.    STRPTR varname = NULL;
  2213.    UWORD count = 0;
  2214.    TEXT numbuff[LEN_NUMBER+1];
  2215.    struct AreaNode *current, *current0;
  2216.    UBYTE curraccess;
  2217.    BOOL stop = FALSE;
  2218.  
  2219.    varname = (STRPTR)rxargv[1];
  2220.    if (strlen(varname) > LEN_REXXVAR)
  2221.       {
  2222.       RexxErr(ERR_VARNAME_TOO_LONG);
  2223.       return;
  2224.       }
  2225.  
  2226.    TakeASem(FALSE);
  2227.  
  2228.    if (rxargv[0])
  2229.       {
  2230.       current = ChangeArea((STRPTR)rxargv[0]);
  2231.       if (!current)
  2232.          {
  2233.          DropASem();
  2234.          RexxErr(ERR_NO_SUCH_AREA);
  2235.          return;
  2236.          }
  2237.       }
  2238.    else
  2239.       {
  2240.       current = KMS_LC->Session.CurrentArea;
  2241.       if (!current)
  2242.          {
  2243.          DropASem();
  2244.          RexxErr(ERR_NO_SUCH_AREA);
  2245.          return;
  2246.          }
  2247.       }
  2248.  
  2249.    if (!current->AreaData.Daughter)
  2250.       {
  2251.       DropASem();
  2252.       SetARexxVarNum(msg, "0", varname, 0);
  2253.       return;
  2254.       }
  2255.  
  2256.    current0 = current;
  2257.  
  2258.    while(current)
  2259.       {
  2260.       /* Nächste Area */
  2261.  
  2262.       if (current->AreaData.Daughter && !stop)
  2263.          current = SetArea(current->AreaData.Daughter);
  2264.       else if (current->AreaData.Next)
  2265.          {
  2266.          current = SetArea(current->AreaData.Next);
  2267.          stop = FALSE;
  2268.          }
  2269.       else if (current->AreaData.Mother)
  2270.          {
  2271.          current = SetArea(current->AreaData.Mother);
  2272.          stop = TRUE;
  2273.          }
  2274.       else
  2275.          {
  2276.          current = NULL;
  2277.          stop = TRUE;
  2278.          }
  2279.  
  2280.       if (current && current->AreaData.Mother == current0->AreaData.Mother)
  2281.          current = NULL;
  2282.  
  2283.       /* Areadaten ausgeben */
  2284.  
  2285.       if (current && !stop && (curraccess = CheckAccess(current)))
  2286.          {
  2287.          SelectArea(current->AreaData.MBName);
  2288.  
  2289.          /* Nächste Gruppe verarbeiten */
  2290.  
  2291.          count++;
  2292.  
  2293.          CreatePath(current);
  2294.  
  2295.          SetARexxVarNum(msg, PathString, varname, count);
  2296.          }
  2297.       }
  2298.  
  2299.    DropASem();
  2300.  
  2301.    sprintf(numbuff, "%d", count);
  2302.    SetARexxVarNum(msg, numbuff, varname, 0);
  2303.    }
  2304.  
  2305. ///
  2306.  
  2307. /***************************************
  2308.  * Rexx-Kommando "SPYWIN"              *
  2309.  ***************************************
  2310.  * I: Parameterstring                  *
  2311.  * O: ---                              *
  2312.  ***************************************/
  2313.  
  2314. /// Rexx_SPYWIN
  2315.  
  2316. /* "OPEN/K,CLOSE/S,SUSPEND/S,CONTINUE/S" */
  2317.  
  2318. VOID Rexx_SPYWIN(struct RexxMsg *msg, LONG rxargv[])
  2319.    {
  2320.    if (rxargv[0]) /* OPEN/K */
  2321.       {
  2322.       if (strlen((STRPTR)rxargv[0]))
  2323.          {
  2324.          if (strlen((STRPTR)rxargv[0])+1 <= sizeof(KMS_LC->SpyWin))
  2325.             strcpy(KMS_LC->SpyWin, (STRPTR)rxargv[0]);
  2326.          else
  2327.             {
  2328.             RexxErr(ERR_INVALID_PARAMS);
  2329.             return;
  2330.             }
  2331.          }
  2332.       else if (!strlen(KMS_LC->SpyWin))
  2333.          strcpy(KMS_LC->SpyWin, "CON:");
  2334.  
  2335.       if (!KMS_LC->SpyHandle && strlen(KMS_LC->SpyWin))
  2336.          KMS_LC->SpyHandle = Open(KMS_LC->SpyWin, MODE_OLDFILE);
  2337.  
  2338.       if (KMS_LC->SpyHandle)
  2339.          Spying = TRUE;
  2340.       else
  2341.          {
  2342.          RexxErr(ERR_INVALID_PARAMS);
  2343.          return;
  2344.          }
  2345.       }
  2346.    else if (rxargv[1]) /* CLOSE/S */
  2347.       {
  2348.       if (KMS_LC->SpyHandle)
  2349.          {
  2350.          Close(KMS_LC->SpyHandle);
  2351.          KMS_LC->SpyHandle = NULL;
  2352.          Spying = FALSE;
  2353.          }
  2354.       }
  2355.    else if (rxargv[2]) /* SUSPEND/S */
  2356.       {
  2357.       Spying = FALSE;
  2358.       }
  2359.    else if (rxargv[3]) /* CONTINUE/S */
  2360.       {
  2361.       if (KMS_LC->SpyHandle)
  2362.          Spying = TRUE;
  2363.       }
  2364.    }
  2365.  
  2366. ///
  2367.  
  2368. /***************************************
  2369.  * Userdaten aus Stemvar auslesen      *
  2370.  ***************************************
  2371.  * I: Userdaten *, Rexxmsg *, STRPTR   *
  2372.  * O: ---                              *
  2373.  ***************************************/
  2374.  
  2375. /// "ReadUserStem"
  2376.  
  2377. VOID ReadUserStem(struct Userdaten *user, struct RexxMsg *msg, STRPTR varname)
  2378.    {
  2379.    STRPTR buff;
  2380.  
  2381.    if (GetARexxVarName(msg, &buff, varname, "USERNAME"))
  2382.       {
  2383.       strncpy(user->Name, buff, LEN_USERNAME);
  2384.       user->Name[LEN_USERNAME] = '\0';
  2385.       ConvertSpace(user->Name);
  2386.       }
  2387.    if (GetARexxVarName(msg, &buff, varname, "REALNAME"))
  2388.       {
  2389.       strncpy(user->RealName, buff, LEN_REALNAME);
  2390.       user->RealName[LEN_REALNAME] = '\0';
  2391.       }
  2392.    if (GetARexxVarName(msg, &buff, varname, "LEVEL"))
  2393.       user->Level = atoi(buff);
  2394.    if (GetARexxVarName(msg, &buff, varname, "LASTCALL"))
  2395.       user->LastCall = atol(buff);
  2396.    if (GetARexxVarName(msg, &buff, varname, "CALLS"))
  2397.       user->Calls = atoi(buff);
  2398.    if (GetARexxVarName(msg, &buff, varname, "STREET"))
  2399.       {
  2400.       strncpy(user->Street, buff, LEN_STREET);
  2401.       user->Street[LEN_STREET] = '\0';
  2402.       }
  2403.    if (GetARexxVarName(msg, &buff, varname, "CITY"))
  2404.       {
  2405.       strncpy(user->City, buff, LEN_CITY);
  2406.       user->City[LEN_CITY] = '\0';
  2407.       }
  2408.    if (GetARexxVarName(msg, &buff, varname, "PHONE"))
  2409.       {
  2410.       strncpy(user->Phone, buff, LEN_PHONE);
  2411.       user->Phone[LEN_PHONE] = '\0';
  2412.       }
  2413.    if (GetARexxVarName(msg, &buff, varname, "CHARSET"))
  2414.       user->CharSet = atoi(buff);
  2415.    if (GetARexxVarName(msg, &buff, varname, "FLAGS"))
  2416.       {
  2417.       if (strstr(buff, "[ANSI]"))
  2418.          user->Flags |= UF_EMU_ANSI;
  2419.       if (strstr(buff, "[TTY]"))
  2420.          user->Flags &= ~UF_EMU_ANSI;
  2421.       if (strstr(buff, "[CLS]"))
  2422.          user->Flags |= UF_CLS;
  2423.       if (strstr(buff, "[NOCLS]"))
  2424.          user->Flags &= ~UF_CLS;
  2425.       if (strstr(buff, "[LONGMSGHEAD]"))
  2426.          user->Flags |= UF_HEAD_LONG;
  2427.       if (strstr(buff, "[SHORTMSGHEAD]"))
  2428.          user->Flags &= ~UF_HEAD_LONG;
  2429.       if (strstr(buff, "[INSERT]"))
  2430.          user->Flags |= UF_EDIT_INSERT;
  2431.       if (strstr(buff, "[OVERSTRIKE]"))
  2432.          user->Flags &= ~UF_EDIT_INSERT;
  2433.       if (strstr(buff, "[AUTOLIST]"))
  2434.          user->Flags |= UF_AUTO_LIST;
  2435.       if (strstr(buff, "[NOAUTOLIST]"))
  2436.          user->Flags &= ~UF_AUTO_LIST;
  2437.       if (strstr(buff, "[AUTOAREALIST]"))
  2438.          user->Flags |= UF_AUTO_AREALIST;
  2439.       if (strstr(buff, "[NOAUTOAREALIST]"))
  2440.          user->Flags &= ~UF_AUTO_AREALIST;
  2441.       if (strstr(buff, "[READNEW]"))
  2442.          {
  2443.          user->Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  2444.          user->Flags |= UF_RMODE_NEW;
  2445.          }
  2446.       else if (strstr(buff, "[READSEL]"))
  2447.          {
  2448.          user->Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  2449.          user->Flags |= UF_RMODE_SEL;
  2450.          }
  2451.       else if (strstr(buff, "[READTHREAD]"))
  2452.          {
  2453.          user->Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  2454.          user->Flags |= UF_RMODE_THRD;
  2455.          }
  2456.       else if (strstr(buff, "[READNEXT]"))
  2457.          user->Flags &= ~(UF_RMODE_NEW|UF_RMODE_SEL|UF_RMODE_THRD);
  2458.       if (strstr(buff, "[SCREENED]"))
  2459.          user->Flags |= UF_SCREEN_ED;
  2460.       if (strstr(buff, "[SIMPLEED]"))
  2461.          user->Flags &= ~UF_SCREEN_ED;
  2462.       if (strstr(buff, "[SENDOPTS]"))
  2463.          user->Flags |= UF_EXTSEND;
  2464.       if (strstr(buff, "[NOSENDOPTS]"))
  2465.          user->Flags &= ~UF_EXTSEND;
  2466.       if (strstr(buff, "[PDATSECRET]"))
  2467.          user->Flags |= UF_PDAT_SECRET;
  2468.       if (strstr(buff, "[PDATPUBLIC]"))
  2469.          user->Flags &= ~UF_PDAT_SECRET;
  2470.       }
  2471.    if (GetARexxVarName(msg, &buff, varname, "PROMPT"))
  2472.       {
  2473.       strncpy(user->Prompt, buff, LEN_UPROMPT);
  2474.       user->Prompt[LEN_UPROMPT] = '\0';
  2475.       }
  2476.    if (GetARexxVarName(msg, &buff, varname, "DISKQUOTA"))
  2477.       user->Quota = atoi(buff);
  2478.    if (GetARexxVarName(msg, &buff, varname, "PAGELEN"))
  2479.       user->PageLen = atoi(buff);
  2480.    if (GetARexxVarName(msg, &buff, varname, "LINELEN"))
  2481.       user->LineLen = atoi(buff);
  2482.    if (GetARexxVarName(msg, &buff, varname, "ACCESSBITS"))
  2483.       user->AccessBits = atol(buff);
  2484.    }
  2485.  
  2486. ///
  2487.  
  2488. /************************************
  2489.  * Port-Msg an einen/alle Ports bis *
  2490.  * auf den eigenen senden           *
  2491.  ************************************
  2492.  * I: Rexx-Cmd                      *
  2493.  * O: BOOL Fehler                   *
  2494.  ************************************/
  2495.  
  2496. /// "SendPortMsg"
  2497.  
  2498. BOOL SendPortMsg(STRPTR command, WORD port, UWORD flags)
  2499.    {
  2500.    TEXT target[LEN_NUMBER+4+1];
  2501.    struct KMSNode *member = KMSBase->MemberList.mlh_Head;
  2502.  
  2503.    if (port < 0)
  2504.       {
  2505.       TakeMSem(FALSE);
  2506.  
  2507.       while(member->Node.mln_Succ)
  2508.          {
  2509.          if (member->LCPtr->ID != KMS_LC->ID)
  2510.             {
  2511.             if (*(member->LCPtr->Session.CurrentUser->UserData.Name))
  2512.                {
  2513.                sprintf(target, "KMS.%d", member->LCPtr->ID);
  2514.  
  2515.                if (!(flags & (CM_URGENT|CM_NORMAL)) || (flags & CM_URGENT) || !(member->LCPtr->Session.CommMode & CM_LOCKED))
  2516.                   sendRexxCmd(command, NULL, NULL, NULL, NULL, target);
  2517.                }
  2518.             }
  2519.  
  2520.          member = member->Node.mln_Succ;
  2521.          }
  2522.  
  2523.       DropMSem();
  2524.  
  2525.       return TRUE;
  2526.       }
  2527.    else if (port > 0)
  2528.       {
  2529.       TakeMSem(FALSE);
  2530.  
  2531.       while(member->Node.mln_Succ)
  2532.          {
  2533.          if (member->LCPtr->ID == port)
  2534.             {
  2535.             if (*(member->LCPtr->Session.CurrentUser->UserData.Name))
  2536.                {
  2537.                sprintf(target, "KMS.%d", port);
  2538.  
  2539.                if (!(flags & (CM_URGENT|CM_NORMAL)) || (flags & CM_URGENT) || !(member->LCPtr->Session.CommMode & CM_LOCKED))
  2540.                   {
  2541.                   sendRexxCmd(command, NULL, NULL, NULL, NULL, target);
  2542.                   DropMSem();
  2543.                   return TRUE;
  2544.                   }
  2545.                else
  2546.                   {
  2547.                   DropMSem();
  2548.                   return FALSE;
  2549.                   }
  2550.                }
  2551.             else
  2552.                {
  2553.                DropMSem();
  2554.                return FALSE;
  2555.                }
  2556.             }
  2557.  
  2558.          member = member->Node.mln_Succ;
  2559.          }
  2560.  
  2561.       DropMSem();
  2562.  
  2563.       return FALSE;
  2564.       }
  2565.    }
  2566.  
  2567. ///
  2568.  
  2569. /************************************
  2570.  * KMS-Rexx-Skript ausfuehren       *
  2571.  ************************************
  2572.  * I: Skript-Pfad/Name              *
  2573.  * O: Erfolgreich TRUE/FALSE        *
  2574.  ************************************/
  2575.  
  2576. /// "ExecKMSRexx"
  2577.  
  2578. BPTR SelectOutput(BPTR);
  2579. BPTR SelectInput(BPTR);
  2580.  
  2581. BOOL ExecKMSRexx(STRPTR script)
  2582.    {
  2583.    BPTR oldin = SelectInput(KMS_LC->InHandle);
  2584.    BPTR oldout = SelectOutput(KMS_LC->OutHandle);
  2585.  
  2586.    /* In CON: Modus schalten */
  2587.  
  2588.    if (IsInteractive(KMS_LC->InHandle))
  2589.       SetMode(KMS_LC->InHandle, 0);
  2590.    KMS_LC->RawMode = FALSE;
  2591.  
  2592.    CursorOn();
  2593.  
  2594.    BOOL result = WaitsyncRexxCmd(script, NULL);
  2595.  
  2596.    CursorOff();
  2597.    
  2598.    /* In RAW: Modus zurückschalten */
  2599.  
  2600.    if (IsInteractive(KMS_LC->InHandle))
  2601.       SetMode(KMS_LC->InHandle, 1);
  2602.    KMS_LC->RawMode = TRUE;
  2603.  
  2604.    if (oldout)
  2605.       SelectOutput(oldout);
  2606.    if (oldin)
  2607.       SelectInput(oldin);
  2608.  
  2609.    /* Eventuelles CTRL-C Signal vernichten */
  2610.  
  2611.    SetSignal(0, SIGBREAKF_CTRL_C);
  2612.  
  2613.    return result;
  2614.    }
  2615.  
  2616. ///
  2617.  
  2618. /***************************************
  2619.  * REXX-Kommando-Parser                *
  2620.  ***************************************
  2621.  * I: STRPTR inbuff, UBYTE *argc,      *
  2622.  * I: STRPTR argv[]                    *
  2623.  * O: ---                              *
  2624.  ***************************************/
  2625.  
  2626. /// "RexxCmdParse"
  2627.  
  2628. VOID RexxCmdParse(STRPTR inbuff, UBYTE *argc, STRPTR argv[])
  2629.    {
  2630.    UWORD inzeig = 0;
  2631.    UWORD anfang = 0;
  2632.    TEXT c;
  2633.  
  2634.    if (!inbuff)
  2635.       {
  2636.       /* Token freigeben */
  2637.  
  2638.       for(inzeig = 0; inzeig < *argc; inzeig++)
  2639.          free(argv[inzeig]);
  2640.  
  2641.       return;
  2642.       }
  2643.  
  2644.    /* Hier geht die Parserei los */
  2645.  
  2646.    *argc = 0;
  2647.  
  2648.    while(inbuff[inzeig] == ' ' || inbuff[inzeig] == ',')
  2649.       inzeig++;
  2650.  
  2651.    do
  2652.       {
  2653.       if (inbuff[inzeig] == '"')
  2654.          {
  2655.          inzeig++;
  2656.          anfang = inzeig;
  2657.          while((c = inbuff[inzeig]) != '"' && c != '\0')
  2658.             inzeig++;
  2659.          }
  2660.       else if (inbuff[inzeig] == '\'')
  2661.          {
  2662.          inzeig++;
  2663.          anfang = inzeig;
  2664.          while((c = inbuff[inzeig]) != '\'' && c != '\0')
  2665.             inzeig++;
  2666.          }
  2667.       else if (*argc == 0 && inbuff[inzeig] == '@')
  2668.          {
  2669.          anfang = inzeig;
  2670.          inzeig++;
  2671.          }
  2672.       else
  2673.          {
  2674.          anfang = inzeig;
  2675.          while((c = inbuff[inzeig]) != ' ' && c != ',' && c != '\0')
  2676.             inzeig++;
  2677.          }
  2678.  
  2679.       if (inzeig-anfang >= 0)
  2680.          {
  2681.          argv[*argc] = (STRPTR)malloc(inzeig-anfang+1);
  2682.          if (!argv[*argc])
  2683.             {
  2684.             RexxErr(ERR_OUT_OF_MEMORY);
  2685.             *argc = 0;
  2686.             c = '\0';
  2687.             }
  2688.          else
  2689.             {
  2690.             strncpy(argv[*argc], &inbuff[anfang], inzeig-anfang);
  2691.             argv[*argc][inzeig-anfang] = '\0';
  2692.  
  2693.             (*argc)++;
  2694.             if (c == '"' || c == '\'')
  2695.                inzeig++;
  2696.             while((c = inbuff[inzeig]) == ' ' || c == ',')
  2697.                inzeig++;
  2698.             }
  2699.          }
  2700.       } while(c != '\0' && *argc < REXXCMDARGS);
  2701.    }
  2702.  
  2703. ///
  2704.  
  2705. /***************************************
  2706.  * Stack-Prüfung                       *
  2707.  ***************************************
  2708.  * I: ---                              *
  2709.  * O: TRUE: OK, FALSE: Out Of Memory   *
  2710.  ***************************************/
  2711.  
  2712. /// "CheckStack"
  2713.  
  2714. BOOL CheckStack(VOID)
  2715.    {
  2716.    struct Task *mytask = FindTask(NULL);
  2717.  
  2718.    if (mytask->tc_SPReg - mytask->tc_SPLower > 1024)
  2719.       return TRUE;
  2720.    else
  2721.       return FALSE;
  2722.    }
  2723.  
  2724. ///
  2725.  
  2726.